Sunday, April 4, 2010

Sprite animation and GLTexture usage

In our last post we have talk about GLTexture files to load to our OpenGL ES screen our sprite images we have borrow for our test program. In this post we are going to try and animate our sprites we have currently available. In this case I have decided to borrow the sprites from The Legend of Zelda A Link to the Past looking, up, down, left and right. We store these image files in our Resources folder in our xCode project we have called "Test". In our last post we have modified our header file for EAGLView for OpenGL:

//

// EAGLView.h

// Test

//

// Created by Julio Cruz on 3/31/10.

// Copyright Red Fox Software 2009. All rights reserved.

//



#import

#import

#import

#import

#import "GLTexture.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 EAGLView : UIView {

@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;

NSTimer *animationTimer;

NSTimeInterval animationInterval;

// Create texture image.

GLTexture *diamond[6];

}


@property NSTimeInterval animationInterval;


- (void)startAnimation;

- (void)stopAnimation;

- (void)drawView;


@end


Nothing new in this source file except for GLTexture *diamond[6]; in this case we have a GLTexture array that will take about five unique images to be store in each individual array we have. After we have modified our EAGLView header file we are now really to write the functions to display the images and determine the time frame of each image to be display. In this case in our implementation file of EAGLView we have:

// Define the space to hold the global variables for the frame counter

unsigned int frameCounter;

double totalRenderingTime;


We are going to determine the first frame we have display on our OpenGL screen image and get the current time for our program later on we must determine the starting time and end time to determine our total rendering time. For example source code:


- (void)drawView {

#ifdef DEBUG

double startTime = CFAbsoluteTimeGetCurrent();

#endif

[EAGLContext setCurrentContext:context];

glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

glViewport(0, 0, backingWidth, backingHeight);

// Draw game scene

glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);

[context presentRenderbuffer:GL_RENDERBUFFER_OES];


#ifdef DEBUG

double endTime = CFAbsoluteTimeGetCurrent();

totalRenderingTime += (endTime - startTime);

#endif

}


With CFAbsoluteTimeGetCurrent() function we can obviously determine the current time or our start time. After the game draws the current frame we must store our ending time frame. Later on we must determine the render time or the total frames that we have taken to draw to the screen. This sounds fun and easy however we must now determine when our user wants to tap our screen to see the sprites to animate. For this type of functionality we have to write a touch function:


// Detect touches of the user and animate sprite image.


#pragma mark -

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch = [touches anyObject];

CGPoint point = [touch locationInView: self];

if(point.x >= 0 && point.x <= 160)

{

if(point.y >= 0 && point.y <= 480)

{

// Init images

switch (frameCounter) {

case 1:

diamond[frameCounter] = [[GLTexture alloc] initWithImage:[UIImage imageNamed:@"linklookup.png"]];

[diamond[frameCounter] drawAtPoint:CGPointMake(diamond[frameCounter].contentSize.width, diamond[frameCounter].contentSize.height)];

NSLog(@"Frame Counter: %d", frameCounter);

break;

case 2:

diamond[frameCounter] = [[GLTexture alloc] initWithImage:[UIImage imageNamed:@"linklookdown.png"]];

[diamond[frameCounter] drawAtPoint:CGPointMake(diamond[frameCounter].contentSize.width, diamond[frameCounter].contentSize.height)];

NSLog(@"Frame Counter: %d", frameCounter);

break;

case 3:

diamond[frameCounter] = [[GLTexture alloc] initWithImage:[UIImage imageNamed:@"linklookdown1.png"]];

[diamond[frameCounter] drawAtPoint:CGPointMake(diamond[frameCounter].contentSize.width, diamond[frameCounter].contentSize.height)];

NSLog(@"Frame Counter: %d", frameCounter);

break;

case 4:

diamond[frameCounter] = [[GLTexture alloc] initWithImage:[UIImage imageNamed:@"linklookleft.png"]];

[diamond[frameCounter] drawAtPoint:CGPointMake(diamond[frameCounter].contentSize.width, diamond[frameCounter].contentSize.height)];

NSLog(@"Frame Counter: %d", frameCounter);

break;

case 5:

diamond[frameCounter] = [[GLTexture alloc] initWithImage:[UIImage imageNamed:@"linklookright.png"]];

[diamond[frameCounter] drawAtPoint:CGPointMake(diamond[frameCounter].contentSize.width, diamond[frameCounter].contentSize.height)];

NSLog(@"Frame Counter: %d", frameCounter);

break;

case 6:

frameCounter = 0;

NSLog(@"Frame Counter: %d", frameCounter);

break;

default:

break;

}

}

frameCounter++;

NSLog(@"Frame Counter: %d",frameCounter);

}

}


In this function we have done several important things:

1) Touch function to detect our users taps on the screen.

2) We have specificed in what view: self.

3) We have determine the point in our view. (Left side tap.).

4) Switch statement for frameCounter.

5) If we have any frame we draw and allocate memory for this specific image being call for this frame.

6) If frame equals 6 frameCounter equals 0 to start at the first frame.

Several disadvantages I see from this implementation is that switch statement that takes 6 calls to switch statement to create a new image. Another disadvantage from this implementation function is that we have to allocate memory each time they are being call. This is not good in the perspective that when we want to animate our character we will have a different quad object for OpenGL to draw our images instead of using one quad object to draw all of our image we need to fully animate our sprite. The sprite animation will be in our second part video for next week.

Julio A. Cruz

Friday, April 2, 2010

iPad pricing.

According to Yahoo.com news internet articles the new and improve apps for the iPad would to cost double the amount at minimum from $0.99 dollars to $1.99 dollars for the minimum pricing. Personally it is not a big deal to make the necessary modifications to the apps and even build up new applications for iPad. What really justified just a jacking up of pricing from the small price $0.99 dollars to $1.99 dollars for minimum pricing? I personally think that depending on the magnitude of the application for the iPhone and iPod touch it should be price. Such as my first app that I created for the iPhone and iPod touch which was Dante the Inferno digital textbook which I priced at the lowest price of $0.99 dollars. Would I dare to bump up the pricing just for the reason of the iPad came around or should there be more to the pricing then meets the eye.

Yahoo News Article: http://news.yahoo.com/s/ytech_wguy/20100331/tc_ytech_wguy/ytech_wguy_tc1397_1

Julio A. Cruz