1// 2// testWindowAppAppDelegate.m 3// testWindowApp 4// 5// Created by Jason Rohrer on 12/14/08. 6// Copyright __MyCompanyName__ 2008. All rights reserved. 7// 8 9#import "gameWindowAppDelegate.h" 10 11 12@implementation gameWindowAppDelegate 13 14@synthesize window; 15@synthesize view; 16 17 18- (void)applicationDidFinishLaunching:(UIApplication *)application { 19 20 printf( "App finished launching\n" ); 21 22 printf( "Calling start anim\n" ); 23 [view startAnimation]; 24 printf( "Done starting animation\n" ); 25 26 // Override point for customization after application launch 27 [window makeKeyAndVisible]; 28 29 // Configure and start the accelerometer 30 // off for now 31 //[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 15)]; 32 //[[UIAccelerometer sharedAccelerometer] setDelegate:self]; 33 34 35 36} 37 38 39// UIAccelerometerDelegate method, called when the device accelerates. 40- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { 41 //printf( "%d --- accel called w %f,%f\n", timeOfCall, acceleration.x, acceleration.y ); 42 // low pass filter 43 float filterFactor = 0.5; 44 accelerationBuffer[0] = acceleration.x * filterFactor + (1-filterFactor) * accelerationBuffer[0]; 45 accelerationBuffer[1] = acceleration.y * filterFactor + (1-filterFactor) * accelerationBuffer[1]; 46 accelerationBuffer[2] = acceleration.z * filterFactor + (1-filterFactor) * accelerationBuffer[2]; 47 48 setOrientation( asin( accelerationBuffer[0] ), asin( accelerationBuffer[1] ) ); 49 50} 51 52 53- (void)dealloc { 54 [window release]; 55 [view stopAnimation]; 56 [view release]; 57 58 [super dealloc]; 59} 60 61@end 62 63 64 65 66 67#include "drawIntoScreen.h" 68 69#import <QuartzCore/QuartzCore.h> 70#import <OpenGLES/EAGLDrawable.h> 71 72@implementation MyView 73 74@synthesize animationTimer; 75@synthesize context; 76 77// You must implement this method 78+ (Class)layerClass { 79 return [CAEAGLLayer class]; 80} 81 82 83//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: 84- (id)initWithCoder:(NSCoder*)coder { 85 86 if ((self = [super initWithCoder:coder])) { 87 // Get the layer 88 CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; 89 90 eaglLayer.opaque = YES; 91 eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: 92 [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; 93 94 context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; 95 96 if (!context || ![EAGLContext setCurrentContext:context]) { 97 [self release]; 98 return nil; 99 } 100 101 } 102 return self; 103} 104 105 106 107NSTimeInterval countStartTime; 108int appFrameCount = 0; 109 110- (void)layoutSubviews { 111 [EAGLContext setCurrentContext:context]; 112 [self destroyFramebuffer]; 113 [self createFramebuffer]; 114 115 NSDate *then = [NSDate date]; 116 117 countStartTime = [then timeIntervalSinceReferenceDate]; 118 119 [self drawFrame]; 120} 121 122 123- (BOOL)createFramebuffer { 124 125 glGenFramebuffersOES(1, &viewFramebuffer); 126 glGenRenderbuffersOES(1, &viewRenderbuffer); 127 128 glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 129 glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 130 [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer]; 131 glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); 132 133 glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); 134 glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); 135 136 if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { 137 NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); 138 return NO; 139 } 140 141 glGenTextures( 1, &textureID ); 142 143 return YES; 144} 145 146 147- (void)destroyFramebuffer { 148 149 glDeleteFramebuffersOES(1, &viewFramebuffer); 150 viewFramebuffer = 0; 151 glDeleteRenderbuffersOES(1, &viewRenderbuffer); 152 viewRenderbuffer = 0; 153 154 if(depthRenderbuffer) { 155 glDeleteRenderbuffersOES(1, &depthRenderbuffer); 156 depthRenderbuffer = 0; 157 } 158 159 glDeleteTextures( 1, &textureID ); 160} 161 162 163 164 165 166- (void)setAnimationTimer:(NSTimer *)newTimer { 167 [animationTimer invalidate]; 168 animationTimer = newTimer; 169} 170 171- (void)startAnimation { 172 NSTimeInterval animationInterval = 1 / 15.0; 173 174 self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawFrame) userInfo:nil repeats:YES]; 175 176 177 178 bitmapW = 128; 179 bitmapH = 128; 180 181 int screenPixels = bitmapW * bitmapH; 182 bitmapBytes = screenPixels* 4; 183 184 screenBitmap = (Uint32 *) malloc( bitmapBytes ); 185 /* 186 // for old DrawImage version 187 provider = CGDataProviderCreateWithData( NULL, screenBitmap, screenPixels * 4, NULL ); 188 colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 189 imageRef = CGImageCreate( 190 bitmapW, 191 bitmapH, 192 8, 193 32, 194 4 * bitmapW, 195 colorSpaceRef, 196 kCGImageAlphaNoneSkipLast, 197 provider, 198 NULL, 199 NO, 200 kCGRenderingIntentDefault ); 201 */ 202 initScreenDrawer( screenBitmap, bitmapW, bitmapH ); 203} 204 205 206- (void)stopAnimation { 207 printf( "Stop anim called\n" ); 208 self.animationTimer = nil; 209 210 free( screenBitmap ); 211 212 freeScreenDrawer(); 213} 214 215 216 217 218 219 220 221 222 223 224- (void)drawFrame { 225 // old DrawImage version 226 //[self setNeedsDisplay]; 227 228 229 230 231 const GLfloat squareVertices[] = { 232 -1.6f, -1.6f, 233 1.6f, -1.6f, 234 -1.6f, 1.6f, 235 1.6f, 1.6f, 236 }; 237 /* 238 const GLubyte squareColors[] = { 239 255, 255, 0, 255, 240 0, 255, 255, 255, 241 255, 0, 0, 0, 242 255, 0, 255, 255, 243 }; 244 */ 245 const GLfloat squareTextureCoords[] = { 246 0, 0, 247 1, 0, 248 0, 1, 249 1, 1 250 }; 251 252 [EAGLContext setCurrentContext:context]; 253 254 glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 255 glViewport(0, 0, backingWidth, backingHeight); 256 257 glMatrixMode(GL_PROJECTION); 258 glLoadIdentity(); 259 glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f); 260 261 262 glMatrixMode(GL_MODELVIEW); 263 264 //glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 265 //glClear(GL_COLOR_BUFFER_BIT); 266 267 glVertexPointer(2, GL_FLOAT, 0, squareVertices); 268 glEnableClientState(GL_VERTEX_ARRAY); 269 270 //glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors); 271 //glEnableClientState(GL_COLOR_ARRAY); 272 273 glTexCoordPointer(2, GL_FLOAT, 0, squareTextureCoords); 274 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 275 276 277 // set new texture data 278 drawIntoScreen( screenBitmap, bitmapW, bitmapH ); 279 280 int error; 281 282 GLenum texFormat = GL_RGBA; 283 glBindTexture( GL_TEXTURE_2D, textureID ); 284 285 error = glGetError(); 286 if( error != GL_NO_ERROR ) { // error 287 printf( "Error binding to texture id %d, error = %d\n", 288 (int)textureID, 289 error ); 290 } 291 292 293 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); 294 295 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); 296 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); 297 298 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); 299 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); 300 301 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); 302 303 glTexImage2D( GL_TEXTURE_2D, 0, 304 texFormat, bitmapW, 305 bitmapH, 0, 306 texFormat, GL_UNSIGNED_BYTE, screenBitmap ); 307 308 error = glGetError(); 309 if( error != GL_NO_ERROR ) { // error 310 printf( "Error setting texture data for id %d, error = %d\n", 311 (int)textureID, error ); 312 printf( "Perhaps texture image width or height is not a power of 2\n" 313 "Width = %lu, Height = %lu\n", 314 bitmapW, bitmapH ); 315 } 316 317 318 319 320 glEnable( GL_TEXTURE_2D ); 321 glBindTexture( GL_TEXTURE_2D, textureID ); 322 323 324 325 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 326 327 glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 328 [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 329 330 331 appFrameCount++; 332 333 // disable FPS tracking 334 if( false && appFrameCount > 100 ) { 335 NSDate *now = [NSDate date]; 336 337 NSTimeInterval newStartTime = [now timeIntervalSinceReferenceDate]; 338 339 NSTimeInterval elapsedTime = newStartTime - countStartTime; 340 341 printf( "FPS: %f\n", appFrameCount / elapsedTime ); 342 343 countStartTime = newStartTime; 344 appFrameCount = 0; 345 } 346 347} 348 349 350 351 352/* 353 354// old DrawImage version 355 356 #include <time.h> 357 358 unsigned int appFrameCountStartTime = time( NULL ); 359 360 int appFrameCount = 0; 361 362- (void)drawRect:(CGRect)rect { 363 364 //printf( "Draw Rect called!\n" ); 365 366 drawIntoScreen( screenBitmap, bitmapW, bitmapH ); 367 368 CGContextRef context = UIGraphicsGetCurrentContext(); 369 370 //CGContextRotateCTM ( context, M_PI / 2 ); 371 //CGContextTranslateCTM ( context, 0, -bitmapH ); 372 373 CGRect imageRect = CGRectMake ( 0, 0, bitmapW, bitmapH ); 374 375 CGContextDrawImage(context, imageRect, imageRef ); 376 377 appFrameCount++; 378 379 if( appFrameCount > 100 ) { 380 unsigned int newTime = time( NULL ); 381 unsigned int timeDelta = newTime - appFrameCountStartTime; 382 383 printf( "FPS = %f\n", (double)appFrameCount / (double)timeDelta ); 384 appFrameCount = 0; 385 appFrameCountStartTime = newTime; 386 } 387 388} 389*/ 390 391// Handles the start of a touch 392- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 393{ 394 CGRect bounds = [self bounds]; 395 UITouch* touch = [[event touchesForView:self] anyObject]; 396 397 //Convert touch point from UIView referential to OpenGL one (upside-down flip) 398 CGPoint location = [touch locationInView:self]; 399 location.y = bounds.size.height - location.y; 400 401 touchStartPoint( location.x, location.y ); 402} 403 404 405 406// Handles touch motion 407- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 408{ 409 CGRect bounds = [self bounds]; 410 UITouch* touch = [[event touchesForView:self] anyObject]; 411 412 //Convert touch point from UIView referential to OpenGL one (upside-down flip) 413 CGPoint location = [touch locationInView:self]; 414 location.y = bounds.size.height - location.y; 415 416 touchMovePoint( location.x, location.y ); 417} 418 419 420// Handles touch end 421- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 422{ 423 CGRect bounds = [self bounds]; 424 UITouch* touch = [[event touchesForView:self] anyObject]; 425 426 //Convert touch point from UIView referential to OpenGL one (upside-down flip) 427 CGPoint location = [touch locationInView:self]; 428 location.y = bounds.size.height - location.y; 429 430 touchEndPoint( location.x, location.y ); 431} 432 433 434@end 435