diff options
-rwxr-xr-x | configure | 237 | ||||
-rw-r--r-- | configure.in | 52 | ||||
-rw-r--r-- | include/SDL_config.h.in | 1 | ||||
-rw-r--r-- | src/render/opengles/SDL_glesfuncs.h | 30 | ||||
-rwxr-xr-x | src/render/opengles/SDL_render_gles.c | 186 | ||||
-rw-r--r-- | src/render/opengles2/SDL_gles2funcs.h | 42 | ||||
-rwxr-xr-x | src/render/opengles2/SDL_render_gles2.c | 261 | ||||
-rwxr-xr-x | src/video/SDL_sysvideo.h | 2 | ||||
-rwxr-xr-x | src/video/SDL_video.c | 5 | ||||
-rwxr-xr-x | src/video/x11/SDL_x11opengles.c | 64 | ||||
-rwxr-xr-x | src/video/x11/SDL_x11opengles.h | 1 | ||||
-rwxr-xr-x | src/video/x11/SDL_x11video.c | 8 | ||||
-rwxr-xr-x | src/video/x11/SDL_x11window.c | 20 | ||||
-rwxr-xr-x | test/configure | 15 | ||||
-rw-r--r-- | test/configure.in | 15 |
15 files changed, 707 insertions, 232 deletions
@@ -1562,6 +1562,7 @@ Optional Features: [default=yes] --enable-video-dummy use dummy video driver [default=yes] --enable-video-opengl include OpenGL support [default=yes] + --enable-video-opengles include OpenGL ES support [default=yes] --enable-input-events use Linux 2.4 unified input interface [default=yes] --enable-input-tslib use the Touchscreen library for input @@ -3772,13 +3773,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3775: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3776: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3778: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3779: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3781: output\"" >&5) + (eval echo "\"\$as_me:3782: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5005,7 +5006,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5008 "configure"' > conftest.$ac_ext + echo '#line 5009 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7166,11 +7167,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7169: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7170: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7173: \$? = $ac_status" >&5 + echo "$as_me:7174: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7505,11 +7506,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7508: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7509: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7512: \$? = $ac_status" >&5 + echo "$as_me:7513: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7610,11 +7611,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7613: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7614: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7617: \$? = $ac_status" >&5 + echo "$as_me:7618: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7665,11 +7666,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7668: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7669: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7672: \$? = $ac_status" >&5 + echo "$as_me:7673: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10423,7 +10424,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10426 "configure" +#line 10427 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10519,7 +10520,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10522 "configure" +#line 10523 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14201,11 +14202,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14204: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14205: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14208: \$? = $ac_status" >&5 + echo "$as_me:14209: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14300,11 +14301,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14303: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14304: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14307: \$? = $ac_status" >&5 + echo "$as_me:14308: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14352,11 +14353,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14355: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14356: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14359: \$? = $ac_status" >&5 + echo "$as_me:14360: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -23752,6 +23753,201 @@ _ACEOF fi } +# Check whether --enable-video-opengles was given. +if test "${enable_video_opengles+set}" = set; then + enableval=$enable_video_opengles; +else + enable_video_opengles=yes +fi + + +CheckOpenGLESX11() +{ + if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then + { echo "$as_me:$LINENO: checking for OpenGL ES (EGL) support" >&5 +echo $ECHO_N "checking for OpenGL ES (EGL) support... $ECHO_C" >&6; } + video_opengles=no + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include <EGL/egl.h> + +int +main () +{ + + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + video_opengles=yes + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { echo "$as_me:$LINENO: result: $video_opengles" >&5 +echo "${ECHO_T}$video_opengles" >&6; } + if test x$video_opengles = xyes; then + { echo "$as_me:$LINENO: checking for OpenGL ES v1 headers" >&5 +echo $ECHO_N "checking for OpenGL ES v1 headers... $ECHO_C" >&6; } + video_opengles_v1=no + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include <GLES/gl.h> + #include <GLES/glext.h> + +int +main () +{ + + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + video_opengles_v1=yes + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { echo "$as_me:$LINENO: result: $video_opengles_v1" >&5 +echo "${ECHO_T}$video_opengles_v1" >&6; } + if test x$video_opengles_v1 = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define SDL_VIDEO_OPENGL_ES 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define SDL_VIDEO_RENDER_OGL_ES 1 +_ACEOF + + fi + { echo "$as_me:$LINENO: checking for OpenGL ES v2 headers" >&5 +echo $ECHO_N "checking for OpenGL ES v2 headers... $ECHO_C" >&6; } + video_opengles_v2=no + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include <GLES2/gl2.h> + #include <GLES2/gl2ext.h> + +int +main () +{ + + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + video_opengles_v2=yes + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { echo "$as_me:$LINENO: result: $video_opengles_v2" >&5 +echo "${ECHO_T}$video_opengles_v2" >&6; } + if test x$video_opengles_v2 = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define SDL_VIDEO_OPENGL_ES2 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define SDL_VIDEO_RENDER_OGL_ES2 1 +_ACEOF + + fi + fi + fi +} + CheckWINDOWSGL() { if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then @@ -27000,6 +27196,7 @@ case "$host" in CheckDirectFB CheckFusionSound CheckOpenGLX11 + CheckOpenGLESX11 CheckInputEvents CheckTslib CheckUSBHID diff --git a/configure.in b/configure.in index 23275438..9e6b5c2e 100644 --- a/configure.in +++ b/configure.in @@ -1474,6 +1474,57 @@ CheckOpenGLX11() fi } +dnl Check to see if OpenGL ES support is desired +AC_ARG_ENABLE(video-opengles, +AC_HELP_STRING([--enable-video-opengles], [include OpenGL ES support [[default=yes]]]), + , enable_video_opengles=yes) + +dnl Find OpenGL ES +CheckOpenGLESX11() +{ + if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then + AC_MSG_CHECKING(for OpenGL ES (EGL) support) + video_opengles=no + AC_TRY_COMPILE([ + #include <EGL/egl.h> + ],[ + ],[ + video_opengles=yes + ]) + AC_MSG_RESULT($video_opengles) + if test x$video_opengles = xyes; then + AC_MSG_CHECKING(for OpenGL ES v1 headers) + video_opengles_v1=no + AC_TRY_COMPILE([ + #include <GLES/gl.h> + #include <GLES/glext.h> + ],[ + ],[ + video_opengles_v1=yes + ]) + AC_MSG_RESULT($video_opengles_v1) + if test x$video_opengles_v1 = xyes; then + AC_DEFINE(SDL_VIDEO_OPENGL_ES, 1, [ ]) + AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES, 1, [ ]) + fi + AC_MSG_CHECKING(for OpenGL ES v2 headers) + video_opengles_v2=no + AC_TRY_COMPILE([ + #include <GLES2/gl2.h> + #include <GLES2/gl2ext.h> + ],[ + ],[ + video_opengles_v2=yes + ]) + AC_MSG_RESULT($video_opengles_v2) + if test x$video_opengles_v2 = xyes; then + AC_DEFINE(SDL_VIDEO_OPENGL_ES2, 1, [ ]) + AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES2, 1, [ ]) + fi + fi + fi +} + dnl Check for Windows OpenGL CheckWINDOWSGL() { @@ -2043,6 +2094,7 @@ case "$host" in CheckDirectFB CheckFusionSound CheckOpenGLX11 + CheckOpenGLESX11 CheckInputEvents CheckTslib CheckUSBHID diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index e1932400..78b04b52 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -271,6 +271,7 @@ #undef SDL_VIDEO_RENDER_D3D #undef SDL_VIDEO_RENDER_OGL #undef SDL_VIDEO_RENDER_OGL_ES +#undef SDL_VIDEO_RENDER_OGL_ES2 #undef SDL_VIDEO_RENDER_DIRECTFB /* Enable OpenGL support */ diff --git a/src/render/opengles/SDL_glesfuncs.h b/src/render/opengles/SDL_glesfuncs.h new file mode 100644 index 00000000..8edb2470 --- /dev/null +++ b/src/render/opengles/SDL_glesfuncs.h @@ -0,0 +1,30 @@ +SDL_PROC(void, glBindTexture, (GLenum, GLuint)) +SDL_PROC(void, glBlendFunc, (GLenum, GLenum)) +SDL_PROC(void, glClear, (GLbitfield)) +SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf)) +SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat)) +SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *)) +SDL_PROC(void, glDisable, (GLenum)) +SDL_PROC(void, glDisableClientState, (GLenum array)) +SDL_PROC(void, glDrawArrays, (GLenum, GLint, GLsizei)) +SDL_PROC(void, glDrawTexiOES, (GLint, GLint, GLint, GLint, GLint)) +SDL_PROC(void, glEnable, (GLenum)) +SDL_PROC(void, glEnableClientState, (GLenum)) +SDL_PROC(void, glGenTextures, (GLsizei, GLuint *)) +SDL_PROC(GLenum, glGetError, (void)) +SDL_PROC(void, glGetIntegerv, (GLenum, GLint *)) +SDL_PROC(void, glLoadIdentity, (void)) +SDL_PROC(void, glMatrixMode, (GLenum)) +SDL_PROC(void, glOrthof, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +SDL_PROC(void, glPixelStorei, (GLenum, GLint)) +SDL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*)) +SDL_PROC(void, glTexCoordPointer, (GLint, GLenum, GLsizei, const GLvoid *)) +SDL_PROC(void, glTexEnvf, (GLenum, GLenum, GLfloat)) +SDL_PROC(void, glTexImage2D, (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +SDL_PROC(void, glTexParameteri, (GLenum, GLenum, GLint)) +SDL_PROC(void, glTexParameteriv, (GLenum, GLenum, const GLint *)) +SDL_PROC(void, glTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +SDL_PROC(void, glVertexPointer, (GLint, GLenum, GLsizei, const GLvoid *)) +SDL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei)) + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/opengles/SDL_render_gles.c b/src/render/opengles/SDL_render_gles.c index 53125a00..45ae7bb7 100755 --- a/src/render/opengles/SDL_render_gles.c +++ b/src/render/opengles/SDL_render_gles.c @@ -40,6 +40,9 @@ glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height) /* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */ +/* Used to re-create the window with OpenGL capability */ +extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags); + static const float inv255f = 1.0f / 255.0f; static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags); @@ -92,6 +95,10 @@ typedef struct SDL_bool tex_coords; } current; +#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; +#include "SDL_glesfuncs.h" +#undef SDL_PROC + SDL_bool useDrawTexture; SDL_bool GL_OES_draw_texture_supported; } GLES_RenderData; @@ -142,6 +149,26 @@ GLES_SetError(const char *prefix, GLenum result) SDL_SetError("%s: %s", prefix, error); } +static int GLES_LoadFunctions(GLES_RenderData * data) +{ +#ifdef __SDL_NOGETPROCADDR__ +#define SDL_PROC(ret,func,params) data->func=func; +#else +#define SDL_PROC(ret,func,params) \ + do { \ + data->func = SDL_GL_GetProcAddress(#func); \ + if ( ! data->func ) { \ + SDL_SetError("Couldn't load GLES function %s: %s\n", #func, SDL_GetError()); \ + return -1; \ + } \ + } while ( 0 ); +#endif /* _SDL_NOGETPROCADDR_ */ + +#include "SDL_glesfuncs.h" +#undef SDL_PROC + return 0; +} + static SDL_GLContext SDL_CurrentContext = NULL; static int @@ -176,14 +203,14 @@ GLES_ResetState(SDL_Renderer *renderer) data->current.blendMode = -1; data->current.tex_coords = SDL_FALSE; - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); + data->glDisable(GL_DEPTH_TEST); + data->glDisable(GL_CULL_FACE); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + data->glMatrixMode(GL_MODELVIEW); + data->glLoadIdentity(); - glEnableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + data->glEnableClientState(GL_VERTEX_ARRAY); + data->glDisableClientState(GL_TEXTURE_COORD_ARRAY); } SDL_Renderer * @@ -193,6 +220,19 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) SDL_Renderer *renderer; GLES_RenderData *data; GLint value; + Uint32 windowFlags; + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + + windowFlags = SDL_GetWindowFlags(window); + if (!(windowFlags & SDL_WINDOW_OPENGL)) { + if (SDL_RecreateWindow(window, windowFlags | SDL_WINDOW_OPENGL) < 0) { + /* Uh oh, better try to put it back... */ + SDL_RecreateWindow(window, windowFlags); + return NULL; + } + } renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { @@ -227,9 +267,6 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->driverdata = data; renderer->window = window; - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - data->context = SDL_GL_CreateContext(window); if (!data->context) { GLES_DestroyRenderer(renderer); @@ -240,6 +277,11 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) return NULL; } + if (GLES_LoadFunctions(data) < 0) { + GLES_DestroyRenderer(renderer); + return NULL; + } + if (flags & SDL_RENDERER_PRESENTVSYNC) { SDL_GL_SetSwapInterval(1); } else { @@ -262,9 +304,9 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) } #endif - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); + data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); renderer->info.max_texture_width = value; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); + data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); renderer->info.max_texture_height = value; /* Set up parameters for rendering */ @@ -313,6 +355,7 @@ GetScaleQuality(void) static int GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { + GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *data; GLint internalFormat; GLenum format, type; @@ -351,9 +394,9 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) texture->driverdata = data; - glGetError(); - glEnable(GL_TEXTURE_2D); - glGenTextures(1, &data->texture); + renderdata->glGetError(); + renderdata->glEnable(GL_TEXTURE_2D); + renderdata->glGenTextures(1, &data->texture); data->type = GL_TEXTURE_2D; /* no NPOV textures allowed in OpenGL ES (yet) */ @@ -365,17 +408,17 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) data->format = format; data->formattype = type; scaleMode = GetScaleQuality(); - glBindTexture(data->type, data->texture); - glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode); - glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode); - glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + renderdata->glBindTexture(data->type, data->texture); + renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode); + renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode); + renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(data->type, 0, internalFormat, texture_w, + renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0, format, type, NULL); - glDisable(GL_TEXTURE_2D); + renderdata->glDisable(GL_TEXTURE_2D); - result = glGetError(); + result = renderdata->glGetError(); if (result != GL_NO_ERROR) { GLES_SetError("glTexImage2D()", result); return -1; @@ -387,6 +430,7 @@ static int GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { + GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; Uint8 *blob = NULL; Uint8 *src; @@ -421,11 +465,11 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, } /* Create a texture subimage with the supplied data */ - glGetError(); - glEnable(data->type); - glBindTexture(data->type, data->texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexSubImage2D(data->type, + renderdata->glGetError(); + renderdata->glEnable(data->type); + renderdata->glBindTexture(data->type, data->texture); + renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, @@ -438,7 +482,7 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, SDL_free(blob); } - if (glGetError() != GL_NO_ERROR) + if (renderdata->glGetError() != GL_NO_ERROR) { SDL_SetError("Failed to update texture"); return -1; @@ -483,12 +527,12 @@ GLES_UpdateViewport(SDL_Renderer * renderer) return 0; } - glViewport(renderer->viewport.x, renderer->viewport.y, + data->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrthof((GLfloat) 0, + data->glMatrixMode(GL_PROJECTION); + data->glLoadIdentity(); + data->glOrthof((GLfloat) 0, (GLfloat) renderer->viewport.w, (GLfloat) renderer->viewport.h, (GLfloat) 0, 0.0, 1.0); @@ -501,7 +545,7 @@ GLES_SetColor(GLES_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a) Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); if (color != data->current.color) { - glColor4f((GLfloat) r * inv255f, + data->glColor4f((GLfloat) r * inv255f, (GLfloat) g * inv255f, (GLfloat) b * inv255f, (GLfloat) a * inv255f); @@ -515,23 +559,23 @@ GLES_SetBlendMode(GLES_RenderData * data, int blendMode) if (blendMode != data->current.blendMode) { switch (blendMode) { case SDL_BLENDMODE_NONE: - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glDisable(GL_BLEND); + data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + data->glDisable(GL_BLEND); break; case SDL_BLENDMODE_BLEND: - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + data->glEnable(GL_BLEND); + data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; case SDL_BLENDMODE_ADD: - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + data->glEnable(GL_BLEND); + data->glBlendFunc(GL_SRC_ALPHA, GL_ONE); break; case SDL_BLENDMODE_MOD: - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable(GL_BLEND); - glBlendFunc(GL_ZERO, GL_SRC_COLOR); + data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + data->glEnable(GL_BLEND); + data->glBlendFunc(GL_ZERO, GL_SRC_COLOR); break; } data->current.blendMode = blendMode; @@ -543,9 +587,9 @@ GLES_SetTexCoords(GLES_RenderData * data, SDL_bool enabled) { if (enabled != data->current.tex_coords) { if (enabled) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + data->glEnableClientState(GL_TEXTURE_COORD_ARRAY); } else { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + data->glDisableClientState(GL_TEXTURE_COORD_ARRAY); } data->current.tex_coords = enabled; } @@ -571,14 +615,16 @@ GLES_SetDrawingState(SDL_Renderer * renderer) static int GLES_RenderClear(SDL_Renderer * renderer) { + GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLES_ActivateRenderer(renderer); - glClearColor((GLfloat) renderer->r * inv255f, + data->glClearColor((GLfloat) renderer->r * inv255f, (GLfloat) renderer->g * inv255f, (GLfloat) renderer->b * inv255f, (GLfloat) renderer->a * inv255f); - glClear(GL_COLOR_BUFFER_BIT); + data->glClear(GL_COLOR_BUFFER_BIT); return 0; } @@ -587,6 +633,7 @@ static int GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, int count) { + GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; int i; GLshort *vertices; @@ -597,8 +644,8 @@ GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, vertices[2*i+0] = (GLshort)points[i].x; vertices[2*i+1] = (GLshort)points[i].y; } - glVertexPointer(2, GL_SHORT, 0, vertices); - glDrawArrays(GL_POINTS, 0, count); + data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glDrawArrays(GL_POINTS, 0, count); SDL_stack_free(vertices); return 0; @@ -608,6 +655,7 @@ static int GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, int count) { + GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; int i; GLshort *vertices; @@ -618,16 +666,16 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, vertices[2*i+0] = (GLshort)points[i].x; vertices[2*i+1] = (GLshort)points[i].y; } - glVertexPointer(2, GL_SHORT, 0, vertices); + data->glVertexPointer(2, GL_SHORT, 0, vertices); if (count > 2 && points[0].x == points[count-1].x && points[0].y == points[count-1].y) { /* GL_LINE_LOOP takes care of the final segment */ --count; - glDrawArrays(GL_LINE_LOOP, 0, count); + data->glDrawArrays(GL_LINE_LOOP, 0, count); } else { - glDrawArrays(GL_LINE_STRIP, 0, count); + data->glDrawArrays(GL_LINE_STRIP, 0, count); /* We need to close the endpoint of the line */ - glDrawArrays(GL_POINTS, count-1, 1); + data->glDrawArrays(GL_POINTS, count-1, 1); } SDL_stack_free(vertices); @@ -638,6 +686,7 @@ static int GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) { + GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; int i; GLES_SetDrawingState(renderer); @@ -658,8 +707,8 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, vertices[6] = maxx; vertices[7] = maxy; - glVertexPointer(2, GL_SHORT, 0, vertices); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } return 0; @@ -677,9 +726,9 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, GLES_ActivateRenderer(renderer); - glEnable(GL_TEXTURE_2D); + data->glEnable(GL_TEXTURE_2D); - glBindTexture(texturedata->type, texturedata->texture); + data->glBindTexture(texturedata->type, texturedata->texture); if (texture->modMode) { GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a); @@ -702,9 +751,9 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, cropRect[1] = srcrect->y + srcrect->h; cropRect[2] = srcrect->w; cropRect[3] = -srcrect->h; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, + data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); - glDrawTexiOES(renderer->viewport.x + dstrect->x, + data->glDrawTexiOES(renderer->viewport.x + dstrect->x, h - (renderer->viewport.y + dstrect->y) - dstrect->h, 0, dstrect->w, dstrect->h); } else { @@ -744,11 +793,11 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, texCoords[6] = maxu; texCoords[7] = maxv; - glVertexPointer(2, GL_SHORT, 0, vertices); - glTexCoordPointer(2, GL_FLOAT, 0, texCoords); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } - glDisable(GL_TEXTURE_2D); + data->glDisable(GL_TEXTURE_2D); return 0; } @@ -757,6 +806,7 @@ static int GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch) { + GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888; void *temp_pixels; @@ -776,9 +826,9 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, SDL_GetWindowSize(window, &w, &h); - glPixelStorei(GL_PACK_ALIGNMENT, 1); + data->glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, + data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); /* Flip the rows to be top-down */ @@ -815,6 +865,8 @@ GLES_RenderPresent(SDL_Renderer * renderer) static void GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { + GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; + GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; GLES_ActivateRenderer(renderer); @@ -823,7 +875,7 @@ GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) return; } if (data->texture) { - glDeleteTextures(1, &data->texture); + renderdata->glDeleteTextures(1, &data->texture); } if (data->pixels) { SDL_free(data->pixels); diff --git a/src/render/opengles2/SDL_gles2funcs.h b/src/render/opengles2/SDL_gles2funcs.h new file mode 100644 index 00000000..fe143c95 --- /dev/null +++ b/src/render/opengles2/SDL_gles2funcs.h @@ -0,0 +1,42 @@ +SDL_PROC(void, glActiveTexture, (GLenum)) +SDL_PROC(void, glAttachShader, (GLuint, GLuint)) +SDL_PROC(void, glBindAttribLocation, (GLuint, GLuint, const char *)) +SDL_PROC(void, glBindTexture, (GLenum, GLuint)) +SDL_PROC(void, glBlendFunc, (GLenum, GLenum)) +SDL_PROC(void, glClear, (GLbitfield)) +SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf)) +SDL_PROC(void, glCompileShader, (GLuint)) +SDL_PROC(GLuint, glCreateProgram, (void)) +SDL_PROC(GLuint, glCreateShader, (GLenum)) +SDL_PROC(void, glDeleteProgram, (GLuint)) +SDL_PROC(void, glDeleteShader, (GLuint)) +SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *)) +SDL_PROC(void, glDisable, (GLenum)) +SDL_PROC(void, glDisableVertexAttribArray, (GLuint)) +SDL_PROC(void, glDrawArrays, (GLenum, GLint, GLsizei)) +SDL_PROC(void, glEnable, (GLenum)) +SDL_PROC(void, glEnableVertexAttribArray, (GLuint)) +SDL_PROC(void, glFinish, (void)) +SDL_PROC(void, glGenTextures, (GLsizei, GLuint *)) +SDL_PROC(void, glGetBooleanv, (GLenum, GLboolean *)) +SDL_PROC(const GLubyte *, glGetString, (GLenum)) +SDL_PROC(GLenum, glGetError, (void)) +SDL_PROC(void, glGetIntegerv, (GLenum, GLint *)) +SDL_PROC(void, glGetProgramiv, (GLuint, GLenum, GLint *)) +SDL_PROC(void, glGetShaderInfoLog, (GLuint, GLsizei, GLsizei *, char *)) +SDL_PROC(void, glGetShaderiv, (GLuint, GLenum, GLint *)) +SDL_PROC(GLint, glGetUniformLocation, (GLuint, const char *)) +SDL_PROC(void, glLinkProgram, (GLuint)) +SDL_PROC(void, glPixelStorei, (GLenum, GLint)) +SDL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*)) +SDL_PROC(void, glShaderBinary, (GLsizei, const GLuint *, GLenum, const void *, GLsizei)) +SDL_PROC(void, glShaderSource, (GLuint, GLsizei, const char **, const GLint *)) +SDL_PROC(void, glTexImage2D, (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const void *)) +SDL_PROC(void, glTexParameteri, (GLenum, GLenum, GLint)) +SDL_PROC(void, glTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +SDL_PROC(void, glUniform1i, (GLint, GLint)) +SDL_PROC(void, glUniform4f, (GLint, GLfloat, GLfloat, GLfloat, GLfloat)) +SDL_PROC(void, glUniformMatrix4fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +SDL_PROC(void, glUseProgram, (GLuint)) +SDL_PROC(void, glVertexAttribPointer, (GLuint, GLint, GLenum, GLboolean, GLsizei, const void *)) +SDL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei)) diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 5b238cad..cc275cae 100755 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -27,6 +27,9 @@ #include "../SDL_sysrender.h" #include "SDL_shaders_gles2.h" +/* Used to re-create the window with OpenGL capability */ +extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags); + /************************************************************************************************* * Bootstrap data * *************************************************************************************************/ @@ -128,6 +131,10 @@ typedef struct GLES2_DriverContext SDL_bool tex_coords; } current; +#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; +#include "SDL_gles2funcs.h" +#undef SDL_PROC + int shader_format_count; GLenum *shader_formats; GLES2_ShaderCache shader_cache; @@ -149,6 +156,26 @@ static void GLES2_DestroyRenderer(SDL_Renderer *renderer); static SDL_GLContext SDL_CurrentContext = NULL; +static int GLES2_LoadFunctions(GLES2_DriverContext * data) +{ +#ifdef __SDL_NOGETPROCADDR__ +#define SDL_PROC(ret,func,params) data->func=func; +#else +#define SDL_PROC(ret,func,params) \ + do { \ + data->func = SDL_GL_GetProcAddress(#func); \ + if ( ! data->func ) { \ + SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \ + return -1; \ + } \ + } while ( 0 ); +#endif /* _SDL_NOGETPROCADDR_ */ + +#include "SDL_gles2funcs.h" +#undef SDL_PROC + return 0; +} + static int GLES2_ActivateRenderer(SDL_Renderer * renderer) { @@ -171,6 +198,8 @@ GLES2_ActivateRenderer(SDL_Renderer * renderer) static void GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) { + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { /* Rebind the context to the window area */ SDL_CurrentContext = NULL; @@ -178,7 +207,7 @@ GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) if (event->event == SDL_WINDOWEVENT_MINIMIZED) { /* According to Apple documentation, we need to finish drawing NOW! */ - glFinish(); + rdata->glFinish(); } } @@ -192,7 +221,7 @@ GLES2_UpdateViewport(SDL_Renderer * renderer) return 0; } - glViewport(renderer->viewport.x, renderer->viewport.y, + rdata->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h); return 0; } @@ -212,7 +241,7 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) entry = rdata->shader_cache.head; while (entry) { - glDeleteShader(entry->id); + rdata->glDeleteShader(entry->id); next = entry->next; SDL_free(entry); entry = next; @@ -223,7 +252,7 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) GLES2_ProgramCacheEntry *next; entry = rdata->program_cache.head; while (entry) { - glDeleteProgram(entry->id); + rdata->glDeleteProgram(entry->id); next = entry->next; SDL_free(entry); entry = next; @@ -267,6 +296,7 @@ GetScaleQuality(void) static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) { + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLES2_TextureData *tdata; GLenum format; GLenum type; @@ -316,19 +346,19 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) } /* Allocate the texture */ - glGetError(); - glGenTextures(1, &tdata->texture); - glActiveTexture(GL_TEXTURE0); - glBindTexture(tdata->texture_type, tdata->texture); - glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); - glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); - glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL); - if (glGetError() != GL_NO_ERROR) + rdata->glGetError(); + rdata->glGenTextures(1, &tdata->texture); + rdata->glActiveTexture(GL_TEXTURE0); + rdata->glBindTexture(tdata->texture_type, tdata->texture); + rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); + rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); + rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + rdata->glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL); + if (rdata->glGetError() != GL_NO_ERROR) { SDL_SetError("Texture creation failed"); - glDeleteTextures(1, &tdata->texture); + rdata->glDeleteTextures(1, &tdata->texture); SDL_free(tdata); return -1; } @@ -339,6 +369,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) { + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; GLES2_ActivateRenderer(renderer); @@ -346,7 +377,7 @@ GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) /* Destroy the texture */ if (tdata) { - glDeleteTextures(1, &tdata->texture); + rdata->glDeleteTextures(1, &tdata->texture); SDL_free(tdata->pixel_data); SDL_free(tdata); texture->driverdata = NULL; @@ -386,6 +417,7 @@ static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch) { + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; Uint8 *blob = NULL; Uint8 *src; @@ -393,7 +425,7 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect int y; GLES2_ActivateRenderer(renderer); - + /* Bail out if we're supposed to update an empty rectangle */ if (rect->w <= 0 || rect->h <= 0) return 0; @@ -420,11 +452,11 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect } /* Create a texture subimage with the supplied data */ - glGetError(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(tdata->texture_type, tdata->texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexSubImage2D(tdata->texture_type, + rdata->glGetError(); + rdata->glActiveTexture(GL_TEXTURE0); + rdata->glBindTexture(tdata->texture_type, tdata->texture); + rdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + rdata->glTexSubImage2D(tdata->texture_type, 0, rect->x, rect->y, @@ -437,7 +469,7 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect SDL_free(blob); } - if (glGetError() != GL_NO_ERROR) + if (rdata->glGetError() != GL_NO_ERROR) { SDL_SetError("Failed to update texture"); return -1; @@ -505,33 +537,33 @@ GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex, entry->blend_mode = blendMode; /* Create the program and link it */ - glGetError(); - entry->id = glCreateProgram(); - glAttachShader(entry->id, vertex->id); - glAttachShader(entry->id, fragment->id); - glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position"); - glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord"); - glLinkProgram(entry->id); - glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful); - if (glGetError() != GL_NO_ERROR || !linkSuccessful) + rdata->glGetError(); + entry->id = rdata->glCreateProgram(); + rdata->glAttachShader(entry->id, vertex->id); + rdata->glAttachShader(entry->id, fragment->id); + rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position"); + rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord"); + rdata->glLinkProgram(entry->id); + rdata->glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful); + if (rdata->glGetError() != GL_NO_ERROR || !linkSuccessful) { SDL_SetError("Failed to link shader program"); - glDeleteProgram(entry->id); + rdata->glDeleteProgram(entry->id); SDL_free(entry); return NULL; } /* Predetermine locations of uniform variables */ entry->uniform_locations[GLES2_UNIFORM_PROJECTION] = - glGetUniformLocation(entry->id, "u_projection"); + rdata->glGetUniformLocation(entry->id, "u_projection"); entry->uniform_locations[GLES2_UNIFORM_TEXTURE] = - glGetUniformLocation(entry->id, "u_texture"); + rdata->glGetUniformLocation(entry->id, "u_texture"); entry->uniform_locations[GLES2_UNIFORM_MODULATION] = - glGetUniformLocation(entry->id, "u_modulation"); + rdata->glGetUniformLocation(entry->id, "u_modulation"); entry->uniform_locations[GLES2_UNIFORM_COLOR] = - glGetUniformLocation(entry->id, "u_color"); + rdata->glGetUniformLocation(entry->id, "u_color"); entry->uniform_locations[GLES2_UNIFORM_COLORTABLE] = - glGetUniformLocation(entry->id, "u_colorTable"); + rdata->glGetUniformLocation(entry->id, "u_colorTable"); /* Cache the linked program */ if (rdata->program_cache.head) @@ -559,7 +591,7 @@ GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex, shaderEntry = rdata->program_cache.tail->fragment_shader; if (--shaderEntry->references <= 0) GLES2_EvictShader(renderer, shaderEntry); - glDeleteProgram(rdata->program_cache.tail->id); + rdata->glDeleteProgram(rdata->program_cache.tail->id); rdata->program_cache.tail = rdata->program_cache.tail->prev; SDL_free(rdata->program_cache.tail->next); rdata->program_cache.tail->next = NULL; @@ -628,29 +660,29 @@ GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type, SDL_BlendMode b entry->instance = instance; /* Compile or load the selected shader instance */ - glGetError(); - entry->id = glCreateShader(instance->type); + rdata->glGetError(); + entry->id = rdata->glCreateShader(instance->type); if (instance->format == (GLenum)-1) { - glShaderSource(entry->id, 1, (const char **)&instance->data, NULL); - glCompileShader(entry->id); - glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful); + rdata->glShaderSource(entry->id, 1, (const char **)&instance->data, NULL); + rdata->glCompileShader(entry->id); + rdata->glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful); } else { - glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length); + rdata->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length); compileSuccessful = GL_TRUE; } - if (glGetError() != GL_NO_ERROR || !compileSuccessful) + if (rdata->glGetError() != GL_NO_ERROR || !compileSuccessful) { char *info = NULL; int length = 0; - glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length); + rdata->glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length); if (length > 0) { info = SDL_stack_alloc(char, length); if (info) { - glGetShaderInfoLog(entry->id, length, &length, info); + rdata->glGetShaderInfoLog(entry->id, length, &length, info); } } if (info) { @@ -659,7 +691,7 @@ GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type, SDL_BlendMode b } else { SDL_SetError("Failed to load the shader"); } - glDeleteShader(entry->id); + rdata->glDeleteShader(entry->id); SDL_free(entry); return NULL; } @@ -690,7 +722,7 @@ GLES2_EvictShader(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry) --rdata->shader_cache.count; /* Deallocate the shader */ - glDeleteShader(entry->id); + rdata->glDeleteShader(entry->id); SDL_free(entry); } @@ -746,9 +778,9 @@ GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source, SDL_BlendM goto fault; /* Select that program in OpenGL */ - glGetError(); - glUseProgram(program->id); - if (glGetError() != GL_NO_ERROR) + rdata->glGetError(); + rdata->glUseProgram(program->id); + if (rdata->glGetError() != GL_NO_ERROR) { SDL_SetError("Failed to select program"); goto fault; @@ -799,9 +831,9 @@ GLES2_SetOrthographicProjection(SDL_Renderer *renderer) /* Set the projection matrix */ locProjection = rdata->current_program->uniform_locations[GLES2_UNIFORM_PROJECTION]; - glGetError(); - glUniformMatrix4fv(locProjection, 1, GL_FALSE, (GLfloat *)projection); - if (glGetError() != GL_NO_ERROR) + rdata->glGetError(); + rdata->glUniformMatrix4fv(locProjection, 1, GL_FALSE, (GLfloat *)projection); + if (rdata->glGetError() != GL_NO_ERROR) { SDL_SetError("Failed to set orthographic projection"); return -1; @@ -829,14 +861,16 @@ static void GLES2_RenderPresent(SDL_Renderer *renderer); static int GLES2_RenderClear(SDL_Renderer * renderer) { - GLES2_ActivateRenderer(renderer); + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; - glClearColor((GLfloat) renderer->r * inv255f, + GLES2_ActivateRenderer(renderer); + + rdata->glClearColor((GLfloat) renderer->r * inv255f, (GLfloat) renderer->g * inv255f, (GLfloat) renderer->b * inv255f, (GLfloat) renderer->a * inv255f); - glClear(GL_COLOR_BUFFER_BIT); + rdata->glClear(GL_COLOR_BUFFER_BIT); return 0; } @@ -848,19 +882,19 @@ GLES2_SetBlendMode(GLES2_DriverContext *rdata, int blendMode) switch (blendMode) { default: case SDL_BLENDMODE_NONE: - glDisable(GL_BLEND); + rdata->glDisable(GL_BLEND); break; case SDL_BLENDMODE_BLEND: - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rdata->glEnable(GL_BLEND); + rdata->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; case SDL_BLENDMODE_ADD: - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + rdata->glEnable(GL_BLEND); + rdata->glBlendFunc(GL_SRC_ALPHA, GL_ONE); break; case SDL_BLENDMODE_MOD: - glEnable(GL_BLEND); - glBlendFunc(GL_ZERO, GL_SRC_COLOR); + rdata->glEnable(GL_BLEND); + rdata->glBlendFunc(GL_ZERO, GL_SRC_COLOR); break; } rdata->current.blendMode = blendMode; @@ -872,9 +906,9 @@ GLES2_SetTexCoords(GLES2_DriverContext * rdata, SDL_bool enabled) { if (enabled != rdata->current.tex_coords) { if (enabled) { - glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); + rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); } else { - glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); + rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); } rdata->current.tex_coords = enabled; } @@ -887,7 +921,7 @@ GLES2_SetDrawingState(SDL_Renderer * renderer) int blendMode = renderer->blendMode; GLuint locColor; - glGetError(); + rdata->glGetError(); GLES2_ActivateRenderer(renderer); @@ -901,7 +935,7 @@ GLES2_SetDrawingState(SDL_Renderer * renderer) /* Select the color to draw with */ locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR]; - glUniform4f(locColor, + rdata->glUniform4f(locColor, renderer->r * inv255f, renderer->g * inv255f, renderer->b * inv255f, @@ -912,6 +946,7 @@ GLES2_SetDrawingState(SDL_Renderer * renderer) static int GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count) { + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLfloat *vertices; int idx; @@ -929,11 +964,11 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun vertices[idx * 2] = x; vertices[(idx * 2) + 1] = y; } - glGetError(); - glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); - glDrawArrays(GL_POINTS, 0, count); + rdata->glGetError(); + rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); + rdata->glDrawArrays(GL_POINTS, 0, count); SDL_stack_free(vertices); - if (glGetError() != GL_NO_ERROR) + if (rdata->glGetError() != GL_NO_ERROR) { SDL_SetError("Failed to render lines"); return -1; @@ -944,6 +979,7 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun static int GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count) { + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLfloat *vertices; int idx; @@ -961,17 +997,17 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count vertices[idx * 2] = x; vertices[(idx * 2) + 1] = y; } - glGetError(); - glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); - glDrawArrays(GL_LINE_STRIP, 0, count); + rdata->glGetError(); + rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); + rdata->glDrawArrays(GL_LINE_STRIP, 0, count); /* We need to close the endpoint of the line */ if (count == 2 || points[0].x != points[count-1].x || points[0].y != points[count-1].y) { - glDrawArrays(GL_POINTS, count-1, 1); + rdata->glDrawArrays(GL_POINTS, count-1, 1); } SDL_stack_free(vertices); - if (glGetError() != GL_NO_ERROR) + if (rdata->glGetError() != GL_NO_ERROR) { SDL_SetError("Failed to render lines"); return -1; @@ -982,6 +1018,7 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) { + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLfloat vertices[8]; int idx; @@ -990,7 +1027,7 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) } /* Emit a line loop for each rectangle */ - glGetError(); + rdata->glGetError(); for (idx = 0; idx < count; ++idx) { const SDL_Rect *rect = &rects[idx]; @@ -1007,10 +1044,10 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) vertices[5] = yMax; vertices[6] = xMax; vertices[7] = yMax; - glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); + rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } - if (glGetError() != GL_NO_ERROR) + if (rdata->glGetError() != GL_NO_ERROR) { SDL_SetError("Failed to render lines"); return -1; @@ -1055,14 +1092,14 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s /* Select the target texture */ locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE]; - glGetError(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(tdata->texture_type, tdata->texture); - glUniform1i(locTexture, 0); + rdata->glGetError(); + rdata->glActiveTexture(GL_TEXTURE0); + rdata->glBindTexture(tdata->texture_type, tdata->texture); + rdata->glUniform1i(locTexture, 0); /* Configure color modulation */ locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION]; - glUniform4f(locModulation, + rdata->glUniform4f(locModulation, texture->r * inv255f, texture->g * inv255f, texture->b * inv255f, @@ -1082,7 +1119,7 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s vertices[5] = (GLfloat)(dstrect->y + dstrect->h); vertices[6] = (GLfloat)(dstrect->x + dstrect->w); vertices[7] = (GLfloat)(dstrect->y + dstrect->h); - glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); + rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); texCoords[0] = srcrect->x / (GLfloat)texture->w; texCoords[1] = srcrect->y / (GLfloat)texture->h; texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w; @@ -1091,9 +1128,9 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h; texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w; texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h; - glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - if (glGetError() != GL_NO_ERROR) + rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords); + rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + if (rdata->glGetError() != GL_NO_ERROR) { SDL_SetError("Failed to render texture"); return -1; @@ -1105,6 +1142,7 @@ static int GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch) { + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; SDL_Window *window = renderer->window; Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888; void *temp_pixels; @@ -1124,9 +1162,9 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, SDL_GetWindowSize(window, &w, &h); - glPixelStorei(GL_PACK_ALIGNMENT, 1); + rdata->glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, + rdata->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); /* Flip the rows to be top-down */ @@ -1181,8 +1219,8 @@ GLES2_ResetState(SDL_Renderer *renderer) rdata->current.blendMode = -1; rdata->current.tex_coords = SDL_FALSE; - glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); - glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); + rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); } static SDL_Renderer * @@ -1194,6 +1232,19 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) #ifndef ZUNE_HD GLboolean hasCompiler; #endif + Uint32 windowFlags; + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + + windowFlags = SDL_GetWindowFlags(window); + if (!(windowFlags & SDL_WINDOW_OPENGL)) { + if (SDL_RecreateWindow(window, windowFlags | SDL_WINDOW_OPENGL) < 0) { + /* Uh oh, better try to put it back... */ + SDL_RecreateWindow(window, windowFlags); + return NULL; + } + } /* Create the renderer struct */ renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer)); @@ -1214,9 +1265,6 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) renderer->window = window; /* Create an OpenGL ES 2.0 context */ - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - rdata->context = SDL_GL_CreateContext(window); if (!rdata->context) { @@ -1228,6 +1276,11 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) return NULL; } + if (GLES2_LoadFunctions(rdata) < 0) { + GLES2_DestroyRenderer(renderer); + return NULL; + } + if (flags & SDL_RENDERER_PRESENTVSYNC) { SDL_GL_SetSwapInterval(1); } else { @@ -1239,12 +1292,12 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) /* Determine supported shader formats */ /* HACK: glGetInteger is broken on the Zune HD's compositor, so we just hardcode this */ - glGetError(); + rdata->glGetError(); #ifdef ZUNE_HD nFormats = 1; #else /* !ZUNE_HD */ - glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats); - glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler); + rdata->glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats); + rdata->glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler); if (hasCompiler) ++nFormats; #endif /* ZUNE_HD */ @@ -1259,8 +1312,8 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) #ifdef ZUNE_HD rdata->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV; #else /* !ZUNE_HD */ - glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats); - if (glGetError() != GL_NO_ERROR) + rdata->glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats); + if (rdata->glGetError() != GL_NO_ERROR) { GLES2_DestroyRenderer(renderer); SDL_SetError("Failed to query supported shader formats"); diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 3bb15dd9..c8344298 100755 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -286,7 +286,7 @@ struct SDL_VideoDevice void *driverdata; struct SDL_GLDriverData *gl_data; -#if SDL_VIDEO_DRIVER_PANDORA +#if SDL_VIDEO_OPENGL_ES struct SDL_PrivateGLESData *gles_data; #endif diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index df8d103b..055fc4eb 100755 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -189,6 +189,9 @@ ShouldUseTextureFramebuffer() } return hasAcceleratedOpenGL; } +#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + /* Let's be optimistic about this! */ + return SDL_TRUE; #else return SDL_FALSE; #endif @@ -1138,7 +1141,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) } /* Some platforms have OpenGL enabled by default */ -#if (SDL_VIDEO_OPENGL && __MACOSX__) || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ flags |= SDL_WINDOW_OPENGL; #endif if (flags & SDL_WINDOW_OPENGL) { diff --git a/src/video/x11/SDL_x11opengles.c b/src/video/x11/SDL_x11opengles.c index 586930c2..b9f65350 100755 --- a/src/video/x11/SDL_x11opengles.c +++ b/src/video/x11/SDL_x11opengles.c @@ -25,7 +25,10 @@ #include "SDL_x11video.h" #include "SDL_x11opengles.h" -#define DEFAULT_OPENGL "/usr/lib/libGLES_CM.so" +#define DEFAULT_EGL "/usr/lib/libEGL.so" +#define DEFAULT_OGL_ES2 "/usr/lib/libGLESv2.so" +#define DEFAULT_OGL_ES_PVR "/usr/lib/libGLES_CM.so" +#define DEFAULT_OGL_ES "/usr/lib/libGLESv1_CM.so" #define LOAD_FUNC(NAME) \ *((void**)&_this->gles_data->NAME) = dlsym(handle, #NAME); \ @@ -44,13 +47,15 @@ X11_GLES_GetProcAddress(_THIS, const char *proc) void *handle; void *retval; - handle = _this->gl_config.dll_handle; + handle = _this->gles_data->egl_dll_handle; if (_this->gles_data->eglGetProcAddress) { retval = _this->gles_data->eglGetProcAddress(proc); if (retval) { return retval; } } + + handle = _this->gl_config.dll_handle; #if defined(__OpenBSD__) && !defined(__ELF__) #undef dlsym(x,y); #endif @@ -70,6 +75,7 @@ X11_GLES_UnloadLibrary(_THIS) _this->gles_data->eglTerminate(_this->gles_data->egl_display); dlclose(_this->gl_config.dll_handle); + dlclose(_this->gles_data->egl_dll_handle); _this->gles_data->eglGetProcAddress = NULL; _this->gles_data->eglChooseConfig = NULL; @@ -111,7 +117,7 @@ X11_GLES_LoadLibrary(_THIS, const char *path) dlclose(handle); path = getenv("SDL_VIDEO_GL_DRIVER"); if (path == NULL) { - path = DEFAULT_OPENGL; + path = DEFAULT_EGL; } handle = dlopen(path, dlopen_flags); } @@ -153,6 +159,29 @@ X11_GLES_LoadLibrary(_THIS, const char *path) return -1; } + _this->gles_data->egl_dll_handle = handle; + + path = getenv("SDL_VIDEO_GL_DRIVER"); + handle = dlopen(path, dlopen_flags); + if ((path == NULL) | (handle == NULL)) { + if (_this->gl_config.major_version > 1) { + path = DEFAULT_OGL_ES2; + handle = dlopen(path, dlopen_flags); + } else { + path = DEFAULT_OGL_ES; + handle = dlopen(path, dlopen_flags); + if (handle == NULL) { + path = DEFAULT_OGL_ES_PVR; + handle = dlopen(path, dlopen_flags); + } + } + } + + if (handle == NULL) { + SDL_SetError("Could not initialize OpenGL ES library"); + return -1; + } + _this->gl_config.dll_handle = handle; _this->gl_config.driver_loaded = 1; @@ -218,6 +247,13 @@ X11_GLES_GetVisual(_THIS, Display * display, int screen) attribs[i++] = _this->gl_config.multisamplesamples; } + attribs[i++] = EGL_RENDERABLE_TYPE; + if (_this->gl_config.major_version == 2) { + attribs[i++] = EGL_OPENGL_ES2_BIT; + } else { + attribs[i++] = EGL_OPENGL_ES_BIT; + } + attribs[i++] = EGL_NONE; if (_this->gles_data->eglChooseConfig(_this->gles_data->egl_display, @@ -260,17 +296,25 @@ X11_GLES_GetVisual(_THIS, Display * display, int screen) SDL_GLContext X11_GLES_CreateContext(_THIS, SDL_Window * window) { - int retval; + EGLint context_attrib_list[] = { + EGL_CONTEXT_CLIENT_VERSION, + 1, + EGL_NONE + }; + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; XSync(display, False); + if (_this->gl_config.major_version) { + context_attrib_list[1] = _this->gl_config.major_version; + } _this->gles_data->egl_context = _this->gles_data->eglCreateContext(_this->gles_data->egl_display, _this->gles_data->egl_config, - EGL_NO_CONTEXT, NULL); + EGL_NO_CONTEXT, context_attrib_list); XSync(display, False); if (_this->gles_data->egl_context == EGL_NO_CONTEXT) { @@ -280,12 +324,12 @@ X11_GLES_CreateContext(_THIS, SDL_Window * window) _this->gles_data->egl_active = 1; - if (_this->gles_data->egl_active) - retval = 1; - else - retval = 0; + if (X11_GLES_MakeCurrent(_this, window, context) < 0) { + X11_GLES_DeleteContext(_this, context); + return NULL; + } - return (retval); + return (SDL_GLContext)(1); } int diff --git a/src/video/x11/SDL_x11opengles.h b/src/video/x11/SDL_x11opengles.h index d17e8188..26fc6170 100755 --- a/src/video/x11/SDL_x11opengles.h +++ b/src/video/x11/SDL_x11opengles.h @@ -32,6 +32,7 @@ typedef struct SDL_PrivateGLESData { int egl_active; /* to stop switching drivers while we have a valid context */ XVisualInfo *egl_visualinfo; + void *egl_dll_handle; EGLDisplay egl_display; EGLContext egl_context; /* Current GLES context */ EGLSurface egl_surface; diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 7b31fb24..254714fd 100755 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -34,7 +34,7 @@ #include "SDL_x11shape.h" #include "SDL_x11touch.h" -#if SDL_VIDEO_DRIVER_PANDORA +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 #include "SDL_x11opengles.h" #endif @@ -110,7 +110,7 @@ X11_DeleteDevice(SDL_VideoDevice * device) } SDL_free(data->windowlist); SDL_free(device->driverdata); -#if SDL_VIDEO_DRIVER_PANDORA +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 SDL_free(device->gles_data); #endif SDL_free(device); @@ -143,7 +143,7 @@ X11_CreateDevice(int devindex) } device->driverdata = data; -#if SDL_VIDEO_DRIVER_PANDORA +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 device->gles_data = (struct SDL_PrivateGLESData *) SDL_calloc(1, sizeof(SDL_PrivateGLESData)); if (!device->gles_data) { SDL_OutOfMemory(); @@ -226,7 +226,7 @@ X11_CreateDevice(int devindex) device->GL_SwapWindow = X11_GL_SwapWindow; device->GL_DeleteContext = X11_GL_DeleteContext; #endif -#if SDL_VIDEO_DRIVER_PANDORA +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 device->GL_LoadLibrary = X11_GLES_LoadLibrary; device->GL_GetProcAddress = X11_GLES_GetProcAddress; device->GL_UnloadLibrary = X11_GLES_UnloadLibrary; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 007a81af..9a4e759d 100755 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -31,7 +31,7 @@ #include "SDL_x11mouse.h" #include "SDL_x11shape.h" -#ifdef SDL_VIDEO_DRIVER_PANDORA +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 #include "SDL_x11opengles.h" #endif @@ -289,7 +289,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) XFree(vinfo); } else #endif -#ifdef SDL_VIDEO_DRIVER_PANDORA +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 if (window->flags & SDL_WINDOW_OPENGL) { XVisualInfo *vinfo; @@ -401,17 +401,19 @@ X11_CreateWindow(_THIS, SDL_Window * window) SDL_SetError("Couldn't create window"); return -1; } -#if SDL_VIDEO_DRIVER_PANDORA - /* Create the GLES window surface */ - _this->gles_data->egl_surface = - _this->gles_data->eglCreateWindowSurface(_this->gles_data-> +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + if (window->flags & SDL_WINDOW_OPENGL) { + /* Create the GLES window surface */ + _this->gles_data->egl_surface = + _this->gles_data->eglCreateWindowSurface(_this->gles_data-> egl_display, _this->gles_data->egl_config, (NativeWindowType) w, NULL); - if (_this->gles_data->egl_surface == EGL_NO_SURFACE) { - SDL_SetError("Could not create GLES window surface"); - return -1; + if (_this->gles_data->egl_surface == EGL_NO_SURFACE) { + SDL_SetError("Could not create GLES window surface"); + return -1; + } } #endif diff --git a/test/configure b/test/configure index 2c723905..ce85af5b 100755 --- a/test/configure +++ b/test/configure @@ -3764,12 +3764,10 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #if defined (__QNXNTO__) - #include <GLES/gl.h> - #elif defined (__IPHONEOS__) + #if defined (__IPHONEOS__) #include <OpenGLES/ES1/gl.h> #else - #error "No OpenGL ES support" + #include <GLES/gl.h> #endif /* __QNXNTO__ */ int @@ -3812,11 +3810,12 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $have_opengles" >&5 echo "${ECHO_T}$have_opengles" >&6; } -if test x$have_opengl = xyes; then - CFLAGS="$CFLAGS -DHAVE_OPENGL" - GLLIB="$XPATH $SYS_GL_LIBS" -elif test x$have_opengles = xyes; then +GLLIB="" +if test x$have_opengles = xyes; then CFLAGS="$CFLAGS -DHAVE_OPENGLES" + GLLIB="$XPATH -lGLESv1_CM" +elif test x$have_opengl = xyes; then + CFLAGS="$CFLAGS -DHAVE_OPENGL" GLLIB="$XPATH $SYS_GL_LIBS" else GLLIB="" diff --git a/test/configure.in b/test/configure.in index b24b6a6f..a808d664 100644 --- a/test/configure.in +++ b/test/configure.in @@ -103,12 +103,10 @@ dnl Check for OpenGL ES AC_MSG_CHECKING(for OpenGL ES support) have_opengles=no AC_TRY_COMPILE([ - #if defined (__QNXNTO__) - #include <GLES/gl.h> - #elif defined (__IPHONEOS__) + #if defined (__IPHONEOS__) #include <OpenGLES/ES1/gl.h> #else - #error "No OpenGL ES support" + #include <GLES/gl.h> #endif /* __QNXNTO__ */ ],[ ],[ @@ -116,11 +114,12 @@ have_opengles=yes ]) AC_MSG_RESULT($have_opengles) -if test x$have_opengl = xyes; then - CFLAGS="$CFLAGS -DHAVE_OPENGL" - GLLIB="$XPATH $SYS_GL_LIBS" -elif test x$have_opengles = xyes; then +GLLIB="" +if test x$have_opengles = xyes; then CFLAGS="$CFLAGS -DHAVE_OPENGLES" + GLLIB="$XPATH -lGLESv1_CM" +elif test x$have_opengl = xyes; then + CFLAGS="$CFLAGS -DHAVE_OPENGL" GLLIB="$XPATH $SYS_GL_LIBS" else GLLIB="" |