changeset 2351:d2a519d2cc57 gsoc2008_iphone

SDL_uikitopenglview is an OpenGL ES View class based on the one found in Apple's OpenGL ES based application template. It's created from SDL_uikitopengles.m, normally.
author Holmes Futrell <hfutrell@umail.ucsb.edu>
date Thu, 17 Jul 2008 22:35:59 +0000
parents eb828d6c3efb
children 1ecbeff9eb4c
files src/video/uikit/SDL_uikitopenglview.h src/video/uikit/SDL_uikitopenglview.m
diffstat 2 files changed, 216 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/uikit/SDL_uikitopenglview.h	Thu Jul 17 22:35:59 2008 +0000
@@ -0,0 +1,50 @@
+//
+//  EAGLView.h
+//  test2
+//
+//  Created by Holmes Futrell on 7/11/08.
+//  Copyright __MyCompanyName__ 2008. All rights reserved.
+//
+
+
+#import <UIKit/UIKit.h>
+#import <OpenGLES/EAGL.h>
+#import <OpenGLES/ES1/gl.h>
+#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.
+ */
+@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;
+	
+}
+
+@property (nonatomic, retain, readonly) EAGLContext *context;
+
+- (void)swapBuffers;
+- (void)setCurrentContext;
+
+- (id)initWithFrame:(CGRect)frame
+	retainBacking:(BOOL)retained \
+	rBits:(int)rBits \
+	gBits:(int)gBits \
+	bBits:(int)bBits \
+	aBits:(int)aBits \
+	depthBits:(int)depthBits;
+
+@end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/uikit/SDL_uikitopenglview.m	Thu Jul 17 22:35:59 2008 +0000
@@ -0,0 +1,166 @@
+//
+//  EAGLView.m
+//  test2
+//
+//  Created by Holmes Futrell on 7/11/08.
+//  Copyright __MyCompanyName__ 2008. All rights reserved.
+//
+
+
+
+#import <QuartzCore/QuartzCore.h>
+#import <OpenGLES/EAGLDrawable.h>
+
+#import "SDL_uikitopenglview.h"
+
+// A class extension to declare private methods
+@interface SDL_uikitopenglview (privateMethods)
+
+- (BOOL) createFramebuffer;
+- (void) destroyFramebuffer;
+
+@end
+
+
+@implementation SDL_uikitopenglview
+
+@synthesize context;
+// You must implement this
++ (Class)layerClass {
+	return [CAEAGLLayer class];
+}
+
+/*
+	stencilBits ignored.
+	Right now iPhone stencil buffer doesn't appear supported.  Maybe it will be in the future ... who knows.
+*/
+- (id)initWithFrame:(CGRect)frame \
+	  retainBacking:(BOOL)retained \
+	  rBits:(int)rBits \
+	  gBits:(int)gBits \
+	  bBits:(int)bBits \
+	  aBits:(int)aBits \
+	  depthBits:(int)depthBits \
+{
+	
+	NSString *colorFormat=nil;
+	GLuint depthBufferFormat;
+	BOOL useDepthBuffer;
+	
+	if (rBits == 8 && gBits == 8 && bBits == 8) {
+		/* if user specifically requests rbg888 or some color format higher than 16bpp */
+		colorFormat = kEAGLColorFormatRGBA8;
+	}
+	else {
+		/* default case (faster) */
+		colorFormat = kEAGLColorFormatRGB565;
+	}
+	
+	if (depthBits == 24) {
+		useDepthBuffer = YES;
+		depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
+	}
+	else if (depthBits == 0) {
+		useDepthBuffer = NO;
+	}
+	else {
+		/* default case when depth buffer is not disabled */
+		/* 
+		   strange, even when we use this, we seem to get a 24 bit depth buffer on iPhone.
+		   perhaps that's the only depth format iPhone actually supports
+		*/
+		useDepthBuffer = YES;
+		depthBufferFormat = GL_DEPTH_COMPONENT16_OES;
+	}
+	
+	if ((self = [super initWithFrame:frame])) {
+		// Get the layer
+		CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+		
+		eaglLayer.opaque = YES;
+		eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
+										[NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil];
+		
+		context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1];
+		
+		if (!context || ![EAGLContext setCurrentContext:context]) {
+			[self release];
+			return nil;
+		}
+		
+		/* create the buffers */
+		glGenFramebuffersOES(1, &viewFramebuffer);
+		glGenRenderbuffersOES(1, &viewRenderbuffer);
+		
+		glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
+		glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
+		[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
+		glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
+		
+		glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
+		glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+		
+		if (useDepthBuffer) {
+			glGenRenderbuffersOES(1, &depthRenderbuffer);
+			glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
+			glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthBufferFormat, backingWidth, backingHeight);
+			glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
+		}
+			
+		if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
+			NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
+			return NO;
+		}
+		/* end create buffers */
+		
+		NSLog(@"Done initializing ...");
+		
+	}
+	return self;
+}
+
+- (void)setCurrentContext {
+	[EAGLContext setCurrentContext:context];
+}
+
+
+- (void)swapBuffers {
+	
+	
+	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
+	if (![context presentRenderbuffer:GL_RENDERBUFFER_OES]) {
+		NSLog(@"Could not swap buffers");
+	}
+}
+
+
+- (void)layoutSubviews {
+	[EAGLContext setCurrentContext:context];
+}
+
+- (void)destroyFramebuffer {
+	
+	glDeleteFramebuffersOES(1, &viewFramebuffer);
+	viewFramebuffer = 0;
+	glDeleteRenderbuffersOES(1, &viewRenderbuffer);
+	viewRenderbuffer = 0;
+	
+	if (depthRenderbuffer) {
+		glDeleteRenderbuffersOES(1, &depthRenderbuffer);
+		depthRenderbuffer = 0;
+	}
+}
+
+
+- (void)dealloc {
+		
+	[self destroyFramebuffer];
+	if ([EAGLContext currentContext] == context) {
+		[EAGLContext setCurrentContext:nil];
+	}
+	[context release];	
+	[super dealloc];
+	
+}
+
+@end
\ No newline at end of file