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