#import #import #import "EAGLView.h" #import "QnDMaze_iPhoneAppDelegate.h" #include "Matrix.h" #define DEFAULT_FOV 100.0f #define NEAR_CLIPPING_PLANE 0.5f #define FAR_CLIPPING_PLANE 500.0f #define FADE_INTERVAL 0.3 @interface EAGLView () @property (nonatomic, retain) EAGLContext * context; @property (nonatomic, assign) NSTimer * animationTimer; - (BOOL) createFramebuffer; - (void) destroyFramebuffer; @end @implementation EAGLView @synthesize context; @synthesize animationTimer; @synthesize animationInterval; + (Class) layerClass { return [CAEAGLLayer class]; } - (id) initWithCoder: (NSCoder *) coder { CAEAGLLayer * eaglLayer; self = [super initWithCoder: coder]; if (self == nil) { return nil; } eaglLayer = (CAEAGLLayer *) self.layer; eaglLayer.opaque = YES; eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool: NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1]; if (context == nil || ![EAGLContext setCurrentContext: context]) { [self release]; return nil; } animationInterval = 1.0 / 60.0; return self; } - (void) dealloc { [self stopAnimation]; if ([EAGLContext currentContext] == context) { [EAGLContext setCurrentContext: nil]; } [context release]; [super dealloc]; } - (void) drawView { BOOL first = YES; [EAGLContext setCurrentContext: context]; glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); if (first) { Matrix matrix; glViewport(0, 0, backingWidth, backingHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); matrix = Matrix_perspective(Matrix_identity(), DEFAULT_FOV, ([self frame].size.width / [self frame].size.height), NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); glMultMatrixf(matrix.m); glMatrixMode(GL_MODELVIEW); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); first = NO; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); [appDelegate drawScene]; glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); [context presentRenderbuffer: GL_RENDERBUFFER_OES]; } - (void) layoutSubviews { [EAGLContext setCurrentContext: context]; [self destroyFramebuffer]; [self createFramebuffer]; [self drawView]; } - (BOOL) createFramebuffer { 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); glGenRenderbuffersOES(1, &depthRenderbuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, 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; } return YES; } - (void) destroyFramebuffer { glDeleteFramebuffersOES(1, &viewFramebuffer); viewFramebuffer = 0; glDeleteRenderbuffersOES(1, &viewRenderbuffer); viewRenderbuffer = 0; if (depthRenderbuffer != 0) { glDeleteRenderbuffersOES(1, &depthRenderbuffer); depthRenderbuffer = 0; } } - (void) startAnimation { self.animationTimer = [NSTimer scheduledTimerWithTimeInterval: animationInterval target: self selector: @selector(drawView) userInfo: nil repeats: YES]; } - (void) stopAnimation { self.animationTimer = nil; } - (void) setAnimationTimer: (NSTimer *) newTimer { [animationTimer invalidate]; animationTimer = newTimer; } - (void) setAnimationInterval: (NSTimeInterval) interval { animationInterval = interval; if (animationTimer != nil) { [self stopAnimation]; [self startAnimation]; } } - (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event { UITouch * touch; CGPoint location; CGRect bounds; touch = [[touches allObjects] objectAtIndex: 0]; location = [touch locationInView: self]; bounds = [self frame]; location.x -= bounds.origin.x; location.y -= bounds.origin.y; if (location.x < bounds.size.width / 3 && location.y > bounds.size.height / 3 && location.y < bounds.size.height / 3 * 2) { [appDelegate rotateLeft]; } else if (location.x > bounds.size.width / 3 * 2 && location.y > bounds.size.height / 3 && location.y < bounds.size.height / 3 * 2) { [appDelegate rotateRight]; } else if (location.y < bounds.size.height / 3 && location.x > bounds.size.width / 3 && location.x < bounds.size.width / 3 * 2) { [appDelegate rotateUp]; } else if (location.y > bounds.size.height / 3 * 2 && location.x > bounds.size.width / 3 && location.x < bounds.size.width / 3 * 2) { [appDelegate rotateDown]; } else if (location.x > bounds.size.width / 3 && location.x < bounds.size.width / 3 * 2 && location.y > bounds.size.height / 3 && location.y < bounds.size.height / 3 * 2) { [appDelegate moveForward]; } } @end