changeset 5212:115fff0641ee

Prefer the OpenGL ES 2.0 context when it's available, make it possible to create an OpenGL 2.0 context on iPhoneOS
author Sam Lantinga <slouken@libsdl.org>
date Sun, 06 Feb 2011 10:22:25 -0800
parents 78db79f5a4e2
children 1be088cec098
files src/render/SDL_render.c src/render/SDL_sysrender.h src/render/opengles/SDL_render_gles.c src/render/opengles2/SDL_render_gles2.c src/video/SDL_video.c src/video/uikit/SDL_uikitopengles.m src/video/uikit/SDL_uikitopenglview.h src/video/uikit/SDL_uikitopenglview.m
diffstat 8 files changed, 98 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/src/render/SDL_render.c	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/render/SDL_render.c	Sun Feb 06 10:22:25 2011 -0800
@@ -50,12 +50,12 @@
 #if SDL_VIDEO_RENDER_OGL
     &GL_RenderDriver,
 #endif
+#if SDL_VIDEO_RENDER_OGL_ES2
+    &GLES2_RenderDriver,
+#endif
 #if SDL_VIDEO_RENDER_OGL_ES
     &GLES_RenderDriver,
 #endif
-#if SDL_VIDEO_RENDER_OGL_ES2
-    &GLES2_RenderDriver,
-#endif
 #if SDL_VIDEO_RENDER_DIRECTFB
     &DirectFB_RenderDriver,
 #endif
--- a/src/render/SDL_sysrender.h	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/render/SDL_sysrender.h	Sun Feb 06 10:22:25 2011 -0800
@@ -124,12 +124,12 @@
 #if SDL_VIDEO_RENDER_OGL
 extern SDL_RenderDriver GL_RenderDriver;
 #endif
+#if SDL_VIDEO_RENDER_OGL_ES2
+extern SDL_RenderDriver GLES2_RenderDriver;
+#endif
 #if SDL_VIDEO_RENDER_OGL_ES
 extern SDL_RenderDriver GLES_RenderDriver;
 #endif
-#if SDL_VIDEO_RENDER_OGL_ES2
-extern SDL_RenderDriver GLES2_RenderDriver;
-#endif
 #if SDL_VIDEO_RENDER_DIRECTFB
 extern SDL_RenderDriver DirectFB_RenderDriver;
 #endif
--- a/src/render/opengles/SDL_render_gles.c	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/render/opengles/SDL_render_gles.c	Sun Feb 06 10:22:25 2011 -0800
@@ -184,6 +184,9 @@
 
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
 
+    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);
--- a/src/render/opengles2/SDL_render_gles2.c	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/render/opengles2/SDL_render_gles2.c	Sun Feb 06 10:22:25 2011 -0800
@@ -185,24 +185,29 @@
     GLES2_ProgramCacheEntry *entry;
     GLES2_ProgramCacheEntry *next;
 
-    GLES2_ActivateRenderer(renderer);
+    /* Deallocate everything */
+    if (rdata) {
+        GLES2_ActivateRenderer(renderer);
 
-    /* Deallocate everything */
-    entry = rdata->program_cache.head;
-    while (entry)
-    {
-        glDeleteShader(entry->vertex_shader->id);
-        glDeleteShader(entry->fragment_shader->id);
-        SDL_free(entry->vertex_shader);
-        SDL_free(entry->fragment_shader);
-        glDeleteProgram(entry->id);
-        next = entry->next;
-        SDL_free(entry);
-        entry = next;
+        entry = rdata->program_cache.head;
+        while (entry) {
+            glDeleteShader(entry->vertex_shader->id);
+            glDeleteShader(entry->fragment_shader->id);
+            SDL_free(entry->vertex_shader);
+            SDL_free(entry->fragment_shader);
+            glDeleteProgram(entry->id);
+            next = entry->next;
+            SDL_free(entry);
+            entry = next;
+        }
+        if (rdata->context) {
+            SDL_GL_DeleteContext(rdata->context);
+        }
+        if (rdata->shader_formats) {
+            SDL_free(rdata->shader_formats);
+        }
+        SDL_free(rdata);
     }
-    SDL_GL_DeleteContext(rdata->context);
-    SDL_free(rdata->shader_formats);
-    SDL_free(renderer->driverdata);
     SDL_free(renderer);
 }
 
@@ -1081,12 +1086,15 @@
 
     /* Create the renderer struct */
     renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer));
+    if (!renderer) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
     rdata = (GLES2_DriverContext *)SDL_calloc(1, sizeof(GLES2_DriverContext));
-    if (!renderer)
-    {
+    if (!rdata) {
+        GLES2_DestroyRenderer(renderer);
         SDL_OutOfMemory();
-        SDL_free(renderer);
-        SDL_free(rdata);
         return NULL;
     }
     renderer->info = GLES2_RenderDriver.info;
@@ -1095,17 +1103,18 @@
 
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
 
-    /* Create the GL context */
+    /* 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)
     {
-        SDL_free(renderer);
-        SDL_free(rdata);
+        GLES2_DestroyRenderer(renderer);
         return NULL;
     }
     if (SDL_GL_MakeCurrent(window, rdata->context) < 0) {
-        SDL_free(renderer);
-        SDL_free(rdata);
+        GLES2_DestroyRenderer(renderer);
         return NULL;
     }
 
@@ -1132,9 +1141,8 @@
     rdata->shader_formats = (GLenum *)SDL_calloc(nFormats, sizeof(GLenum));
     if (!rdata->shader_formats)
     {
+        GLES2_DestroyRenderer(renderer);
         SDL_OutOfMemory();
-        SDL_free(renderer);
-        SDL_free(rdata);
         return NULL;
     }
     rdata->shader_format_count = nFormats;
@@ -1144,10 +1152,8 @@
     glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats);
     if (glGetError() != GL_NO_ERROR)
     {
+        GLES2_DestroyRenderer(renderer);
         SDL_SetError("Failed to query supported shader formats");
-        SDL_free(renderer);
-        SDL_free(rdata->shader_formats);
-        SDL_free(rdata);
         return NULL;
     }
     if (hasCompiler)
--- a/src/video/SDL_video.c	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/video/SDL_video.c	Sun Feb 06 10:22:25 2011 -0800
@@ -30,13 +30,17 @@
 #include "SDL_pixels_c.h"
 #include "../events/SDL_events_c.h"
 
+#if SDL_VIDEO_OPENGL
+#include "SDL_opengl.h"
+#endif /* SDL_VIDEO_OPENGL */
+
 #if SDL_VIDEO_OPENGL_ES
 #include "SDL_opengles.h"
 #endif /* SDL_VIDEO_OPENGL_ES */
 
-#if SDL_VIDEO_OPENGL
-#include "SDL_opengl.h"
-#endif /* SDL_VIDEO_OPENGL */
+#if SDL_VIDEO_OPENGL_ES2
+#include "SDL_opengles2.h"
+#endif /* SDL_VIDEO_OPENGL_ES2 */
 
 #include "SDL_syswm.h"
 
@@ -481,8 +485,16 @@
     _this->gl_config.multisamplesamples = 0;
     _this->gl_config.retained_backing = 1;
     _this->gl_config.accelerated = -1;  /* accelerated or not, both are fine */
+#if SDL_VIDEO_OPENGL
     _this->gl_config.major_version = 2;
     _this->gl_config.minor_version = 1;
+#elif SDL_VIDEO_OPENGL_ES2
+    _this->gl_config.major_version = 2;
+    _this->gl_config.minor_version = 0;
+#elif SDL_VIDEO_OPENGL_ES
+    _this->gl_config.major_version = 1;
+    _this->gl_config.minor_version = 1;
+#endif
 
     /* Initialize the video subsystem */
     if (_this->VideoInit(_this) < 0) {
@@ -1897,7 +1909,7 @@
 SDL_bool
 SDL_GL_ExtensionSupported(const char *extension)
 {
-#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
     const char *extensions;
     const char *start;
@@ -1951,7 +1963,7 @@
 int
 SDL_GL_SetAttribute(SDL_GLattr attr, int value)
 {
-#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     int retval;
 
     if (!_this) {
@@ -2032,7 +2044,7 @@
 int
 SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
 {
-#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
     GLenum(APIENTRY * glGetErrorFunc) (void);
     GLenum attrib = 0;
@@ -2068,7 +2080,7 @@
         attrib = GL_ALPHA_BITS;
         break;
     case SDL_GL_DOUBLEBUFFER:
-#ifndef SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL
         attrib = GL_DOUBLEBUFFER;
         break;
 #else
@@ -2084,7 +2096,7 @@
     case SDL_GL_STENCIL_SIZE:
         attrib = GL_STENCIL_BITS;
         break;
-#ifndef SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL
     case SDL_GL_ACCUM_RED_SIZE:
         attrib = GL_ACCUM_RED_BITS;
         break;
@@ -2111,14 +2123,14 @@
         return 0;
 #endif
     case SDL_GL_MULTISAMPLEBUFFERS:
-#ifndef SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL
         attrib = GL_SAMPLE_BUFFERS_ARB;
 #else
         attrib = GL_SAMPLE_BUFFERS;
 #endif
         break;
     case SDL_GL_MULTISAMPLESAMPLES:
-#ifndef SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL
         attrib = GL_SAMPLES_ARB;
 #else
         attrib = GL_SAMPLES;
--- a/src/video/uikit/SDL_uikitopengles.m	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/video/uikit/SDL_uikitopengles.m	Sun Feb 06 10:22:25 2011 -0800
@@ -113,7 +113,8 @@
                                     gBits: _this->gl_config.green_size \
                                     bBits: _this->gl_config.blue_size \
                                     aBits: _this->gl_config.alpha_size \
-                                    depthBits: _this->gl_config.depth_size];
+                                    depthBits: _this->gl_config.depth_size \
+                                    majorVersion: _this->gl_config.major_version];
     
     data->view = view;
     
--- a/src/video/uikit/SDL_uikitopenglview.h	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/video/uikit/SDL_uikitopenglview.h	Sun Feb 06 10:22:25 2011 -0800
@@ -26,26 +26,26 @@
 #import <OpenGLES/ES1/glext.h>
 #import "SDL_uikitview.h"
 /*
-	This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
-	The view content is basically an EAGL surface you render your OpenGL scene into.
-	Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
+    This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
+    The view content is basically an EAGL surface you render your OpenGL scene into.
+    Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
  */
 /* *INDENT-OFF* */
 @interface SDL_uikitopenglview : SDL_uikitview {
-	
+    
 @private
-	/* The pixel dimensions of the backbuffer */
-	GLint backingWidth;
-	GLint backingHeight;
-	
-	EAGLContext *context;
-	
-	/* OpenGL names for the renderbuffer and framebuffers used to render to this view */
-	GLuint viewRenderbuffer, viewFramebuffer;
-	
-	/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
-	GLuint depthRenderbuffer;
-	
+    /* The pixel dimensions of the backbuffer */
+    GLint backingWidth;
+    GLint backingHeight;
+    
+    EAGLContext *context;
+    
+    /* OpenGL names for the renderbuffer and framebuffers used to render to this view */
+    GLuint viewRenderbuffer, viewFramebuffer;
+    
+    /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
+    GLuint depthRenderbuffer;
+    
 }
 
 @property (nonatomic, retain, readonly) EAGLContext *context;
@@ -54,12 +54,13 @@
 - (void)setCurrentContext;
 
 - (id)initWithFrame:(CGRect)frame
-	retainBacking:(BOOL)retained \
-	rBits:(int)rBits \
-	gBits:(int)gBits \
-	bBits:(int)bBits \
-	aBits:(int)aBits \
-	depthBits:(int)depthBits;
+    retainBacking:(BOOL)retained \
+    rBits:(int)rBits \
+    gBits:(int)gBits \
+    bBits:(int)bBits \
+    aBits:(int)aBits \
+    depthBits:(int)depthBits \
+    majorVersion:(int)majorVersion;
 
 @end
 /* *INDENT-ON* */
--- a/src/video/uikit/SDL_uikitopenglview.m	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/video/uikit/SDL_uikitopenglview.m	Sun Feb 06 10:22:25 2011 -0800
@@ -47,6 +47,7 @@
       bBits:(int)bBits \
       aBits:(int)aBits \
       depthBits:(int)depthBits \
+      majorVersion:(int)majorVersion \
 {
     NSString *colorFormat=nil;
     GLuint depthBufferFormat;
@@ -86,8 +87,11 @@
         eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                         [NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil];
         
-        context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1];
-        
+        if (majorVersion > 1) {
+            context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
+        } else {
+            context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1];
+        }
         if (!context || ![EAGLContext setCurrentContext:context]) {
             [self release];
             return nil;