Prefer the OpenGL ES 2.0 context when it's available, make it possible to create an OpenGL 2.0 context on iPhoneOS

This commit is contained in:
Sam Lantinga 2011-02-06 10:22:25 -08:00
parent ccdb593a0b
commit b1c0c48f03
8 changed files with 99 additions and 72 deletions

View file

@ -50,12 +50,12 @@ static const SDL_RenderDriver *render_drivers[] = {
#if SDL_VIDEO_RENDER_OGL #if SDL_VIDEO_RENDER_OGL
&GL_RenderDriver, &GL_RenderDriver,
#endif #endif
#if SDL_VIDEO_RENDER_OGL_ES
&GLES_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_OGL_ES2 #if SDL_VIDEO_RENDER_OGL_ES2
&GLES2_RenderDriver, &GLES2_RenderDriver,
#endif #endif
#if SDL_VIDEO_RENDER_OGL_ES
&GLES_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_DIRECTFB #if SDL_VIDEO_RENDER_DIRECTFB
&DirectFB_RenderDriver, &DirectFB_RenderDriver,
#endif #endif

View file

@ -124,12 +124,12 @@ extern SDL_RenderDriver D3D_RenderDriver;
#if SDL_VIDEO_RENDER_OGL #if SDL_VIDEO_RENDER_OGL
extern SDL_RenderDriver GL_RenderDriver; extern SDL_RenderDriver GL_RenderDriver;
#endif #endif
#if SDL_VIDEO_RENDER_OGL_ES
extern SDL_RenderDriver GLES_RenderDriver;
#endif
#if SDL_VIDEO_RENDER_OGL_ES2 #if SDL_VIDEO_RENDER_OGL_ES2
extern SDL_RenderDriver GLES2_RenderDriver; extern SDL_RenderDriver GLES2_RenderDriver;
#endif #endif
#if SDL_VIDEO_RENDER_OGL_ES
extern SDL_RenderDriver GLES_RenderDriver;
#endif
#if SDL_VIDEO_RENDER_DIRECTFB #if SDL_VIDEO_RENDER_DIRECTFB
extern SDL_RenderDriver DirectFB_RenderDriver; extern SDL_RenderDriver DirectFB_RenderDriver;
#endif #endif

View file

@ -184,6 +184,9 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.flags = SDL_RENDERER_ACCELERATED; 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); data->context = SDL_GL_CreateContext(window);
if (!data->context) { if (!data->context) {
GLES_DestroyRenderer(renderer); GLES_DestroyRenderer(renderer);

View file

@ -185,24 +185,29 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer)
GLES2_ProgramCacheEntry *entry; GLES2_ProgramCacheEntry *entry;
GLES2_ProgramCacheEntry *next; GLES2_ProgramCacheEntry *next;
GLES2_ActivateRenderer(renderer);
/* Deallocate everything */ /* Deallocate everything */
entry = rdata->program_cache.head; if (rdata) {
while (entry) GLES2_ActivateRenderer(renderer);
{
glDeleteShader(entry->vertex_shader->id); entry = rdata->program_cache.head;
glDeleteShader(entry->fragment_shader->id); while (entry) {
SDL_free(entry->vertex_shader); glDeleteShader(entry->vertex_shader->id);
SDL_free(entry->fragment_shader); glDeleteShader(entry->fragment_shader->id);
glDeleteProgram(entry->id); SDL_free(entry->vertex_shader);
next = entry->next; SDL_free(entry->fragment_shader);
SDL_free(entry); glDeleteProgram(entry->id);
entry = next; 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); SDL_free(renderer);
} }
@ -1081,12 +1086,15 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
/* Create the renderer struct */ /* Create the renderer struct */
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer)); renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer));
rdata = (GLES2_DriverContext *)SDL_calloc(1, sizeof(GLES2_DriverContext)); if (!renderer) {
if (!renderer) SDL_OutOfMemory();
{ return NULL;
}
rdata = (GLES2_DriverContext *)SDL_calloc(1, sizeof(GLES2_DriverContext));
if (!rdata) {
GLES2_DestroyRenderer(renderer);
SDL_OutOfMemory(); SDL_OutOfMemory();
SDL_free(renderer);
SDL_free(rdata);
return NULL; return NULL;
} }
renderer->info = GLES2_RenderDriver.info; renderer->info = GLES2_RenderDriver.info;
@ -1095,17 +1103,18 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
renderer->info.flags = SDL_RENDERER_ACCELERATED; 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); rdata->context = SDL_GL_CreateContext(window);
if (!rdata->context) if (!rdata->context)
{ {
SDL_free(renderer); GLES2_DestroyRenderer(renderer);
SDL_free(rdata);
return NULL; return NULL;
} }
if (SDL_GL_MakeCurrent(window, rdata->context) < 0) { if (SDL_GL_MakeCurrent(window, rdata->context) < 0) {
SDL_free(renderer); GLES2_DestroyRenderer(renderer);
SDL_free(rdata);
return NULL; return NULL;
} }
@ -1132,9 +1141,8 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
rdata->shader_formats = (GLenum *)SDL_calloc(nFormats, sizeof(GLenum)); rdata->shader_formats = (GLenum *)SDL_calloc(nFormats, sizeof(GLenum));
if (!rdata->shader_formats) if (!rdata->shader_formats)
{ {
GLES2_DestroyRenderer(renderer);
SDL_OutOfMemory(); SDL_OutOfMemory();
SDL_free(renderer);
SDL_free(rdata);
return NULL; return NULL;
} }
rdata->shader_format_count = nFormats; rdata->shader_format_count = nFormats;
@ -1144,10 +1152,8 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats); glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats);
if (glGetError() != GL_NO_ERROR) if (glGetError() != GL_NO_ERROR)
{ {
GLES2_DestroyRenderer(renderer);
SDL_SetError("Failed to query supported shader formats"); SDL_SetError("Failed to query supported shader formats");
SDL_free(renderer);
SDL_free(rdata->shader_formats);
SDL_free(rdata);
return NULL; return NULL;
} }
if (hasCompiler) if (hasCompiler)

View file

@ -30,13 +30,17 @@
#include "SDL_pixels_c.h" #include "SDL_pixels_c.h"
#include "../events/SDL_events_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 #if SDL_VIDEO_OPENGL_ES
#include "SDL_opengles.h" #include "SDL_opengles.h"
#endif /* SDL_VIDEO_OPENGL_ES */ #endif /* SDL_VIDEO_OPENGL_ES */
#if SDL_VIDEO_OPENGL #if SDL_VIDEO_OPENGL_ES2
#include "SDL_opengl.h" #include "SDL_opengles2.h"
#endif /* SDL_VIDEO_OPENGL */ #endif /* SDL_VIDEO_OPENGL_ES2 */
#include "SDL_syswm.h" #include "SDL_syswm.h"
@ -481,8 +485,16 @@ SDL_VideoInit(const char *driver_name)
_this->gl_config.multisamplesamples = 0; _this->gl_config.multisamplesamples = 0;
_this->gl_config.retained_backing = 1; _this->gl_config.retained_backing = 1;
_this->gl_config.accelerated = -1; /* accelerated or not, both are fine */ _this->gl_config.accelerated = -1; /* accelerated or not, both are fine */
#if SDL_VIDEO_OPENGL
_this->gl_config.major_version = 2; _this->gl_config.major_version = 2;
_this->gl_config.minor_version = 1; _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 */ /* Initialize the video subsystem */
if (_this->VideoInit(_this) < 0) { if (_this->VideoInit(_this) < 0) {
@ -1897,7 +1909,7 @@ SDL_GL_UnloadLibrary(void)
SDL_bool SDL_bool
SDL_GL_ExtensionSupported(const char *extension) 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 GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
const char *extensions; const char *extensions;
const char *start; const char *start;
@ -1951,7 +1963,7 @@ SDL_GL_ExtensionSupported(const char *extension)
int int
SDL_GL_SetAttribute(SDL_GLattr attr, int value) 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; int retval;
if (!_this) { if (!_this) {
@ -2032,7 +2044,7 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value)
int int
SDL_GL_GetAttribute(SDL_GLattr attr, int *value) 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); void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
GLenum(APIENTRY * glGetErrorFunc) (void); GLenum(APIENTRY * glGetErrorFunc) (void);
GLenum attrib = 0; GLenum attrib = 0;
@ -2068,7 +2080,7 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
attrib = GL_ALPHA_BITS; attrib = GL_ALPHA_BITS;
break; break;
case SDL_GL_DOUBLEBUFFER: case SDL_GL_DOUBLEBUFFER:
#ifndef SDL_VIDEO_OPENGL_ES #if SDL_VIDEO_OPENGL
attrib = GL_DOUBLEBUFFER; attrib = GL_DOUBLEBUFFER;
break; break;
#else #else
@ -2084,7 +2096,7 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
case SDL_GL_STENCIL_SIZE: case SDL_GL_STENCIL_SIZE:
attrib = GL_STENCIL_BITS; attrib = GL_STENCIL_BITS;
break; break;
#ifndef SDL_VIDEO_OPENGL_ES #if SDL_VIDEO_OPENGL
case SDL_GL_ACCUM_RED_SIZE: case SDL_GL_ACCUM_RED_SIZE:
attrib = GL_ACCUM_RED_BITS; attrib = GL_ACCUM_RED_BITS;
break; break;
@ -2111,14 +2123,14 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
return 0; return 0;
#endif #endif
case SDL_GL_MULTISAMPLEBUFFERS: case SDL_GL_MULTISAMPLEBUFFERS:
#ifndef SDL_VIDEO_OPENGL_ES #if SDL_VIDEO_OPENGL
attrib = GL_SAMPLE_BUFFERS_ARB; attrib = GL_SAMPLE_BUFFERS_ARB;
#else #else
attrib = GL_SAMPLE_BUFFERS; attrib = GL_SAMPLE_BUFFERS;
#endif #endif
break; break;
case SDL_GL_MULTISAMPLESAMPLES: case SDL_GL_MULTISAMPLESAMPLES:
#ifndef SDL_VIDEO_OPENGL_ES #if SDL_VIDEO_OPENGL
attrib = GL_SAMPLES_ARB; attrib = GL_SAMPLES_ARB;
#else #else
attrib = GL_SAMPLES; attrib = GL_SAMPLES;

View file

@ -113,7 +113,8 @@ SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window)
gBits: _this->gl_config.green_size \ gBits: _this->gl_config.green_size \
bBits: _this->gl_config.blue_size \ bBits: _this->gl_config.blue_size \
aBits: _this->gl_config.alpha_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; data->view = view;

View file

@ -26,26 +26,26 @@
#import <OpenGLES/ES1/glext.h> #import <OpenGLES/ES1/glext.h>
#import "SDL_uikitview.h" #import "SDL_uikitview.h"
/* /*
This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. 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. 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. Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
*/ */
/* *INDENT-OFF* */ /* *INDENT-OFF* */
@interface SDL_uikitopenglview : SDL_uikitview { @interface SDL_uikitopenglview : SDL_uikitview {
@private @private
/* The pixel dimensions of the backbuffer */ /* The pixel dimensions of the backbuffer */
GLint backingWidth; GLint backingWidth;
GLint backingHeight; GLint backingHeight;
EAGLContext *context; EAGLContext *context;
/* OpenGL names for the renderbuffer and framebuffers used to render to this view */ /* OpenGL names for the renderbuffer and framebuffers used to render to this view */
GLuint viewRenderbuffer, viewFramebuffer; GLuint viewRenderbuffer, viewFramebuffer;
/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */ /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
GLuint depthRenderbuffer; GLuint depthRenderbuffer;
} }
@property (nonatomic, retain, readonly) EAGLContext *context; @property (nonatomic, retain, readonly) EAGLContext *context;
@ -54,12 +54,13 @@
- (void)setCurrentContext; - (void)setCurrentContext;
- (id)initWithFrame:(CGRect)frame - (id)initWithFrame:(CGRect)frame
retainBacking:(BOOL)retained \ retainBacking:(BOOL)retained \
rBits:(int)rBits \ rBits:(int)rBits \
gBits:(int)gBits \ gBits:(int)gBits \
bBits:(int)bBits \ bBits:(int)bBits \
aBits:(int)aBits \ aBits:(int)aBits \
depthBits:(int)depthBits; depthBits:(int)depthBits \
majorVersion:(int)majorVersion;
@end @end
/* *INDENT-ON* */ /* *INDENT-ON* */

View file

@ -47,6 +47,7 @@
bBits:(int)bBits \ bBits:(int)bBits \
aBits:(int)aBits \ aBits:(int)aBits \
depthBits:(int)depthBits \ depthBits:(int)depthBits \
majorVersion:(int)majorVersion \
{ {
NSString *colorFormat=nil; NSString *colorFormat=nil;
GLuint depthBufferFormat; GLuint depthBufferFormat;
@ -86,8 +87,11 @@
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil]; [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]) { if (!context || ![EAGLContext setCurrentContext:context]) {
[self release]; [self release];
return nil; return nil;