From 7abdebb6f44049021fe954359d8f167d229c36b0 Mon Sep 17 00:00:00 2001 From: Holmes Futrell Date: Thu, 17 Jul 2008 22:35:59 +0000 Subject: [PATCH] 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. --- src/video/uikit/SDL_uikitopenglview.h | 50 ++++++++ src/video/uikit/SDL_uikitopenglview.m | 166 ++++++++++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 src/video/uikit/SDL_uikitopenglview.h create mode 100644 src/video/uikit/SDL_uikitopenglview.m diff --git a/src/video/uikit/SDL_uikitopenglview.h b/src/video/uikit/SDL_uikitopenglview.h new file mode 100644 index 000000000..fc14b177c --- /dev/null +++ b/src/video/uikit/SDL_uikitopenglview.h @@ -0,0 +1,50 @@ +// +// EAGLView.h +// test2 +// +// Created by Holmes Futrell on 7/11/08. +// Copyright __MyCompanyName__ 2008. All rights reserved. +// + + +#import +#import +#import +#import +#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 diff --git a/src/video/uikit/SDL_uikitopenglview.m b/src/video/uikit/SDL_uikitopenglview.m new file mode 100644 index 000000000..4f5979fb6 --- /dev/null +++ b/src/video/uikit/SDL_uikitopenglview.m @@ -0,0 +1,166 @@ +// +// EAGLView.m +// test2 +// +// Created by Holmes Futrell on 7/11/08. +// Copyright __MyCompanyName__ 2008. All rights reserved. +// + + + +#import +#import + +#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