MilGra
milgra
about
articles
projects

blogroll
bit-101
coding horror
blameit
failblog
beszeljukmac
sghu

navigation
posts
docs
admin

2010-01-18 iPhone openGL ES basics - animation
January 15th, 2010

Lets continue from "iPhone openGL ES basics - textures as point sprites"

Lets move our point sprites around. We need a few instance variables for this in the header. We need an array of GLfloats to store coordinates, two float for storing the two particles directions, the EAGLContext, and a NSTimer for simulation/screen refresh.

#import "GLView.h"
#import <OpenGLES/ES1/glext.h>

@interface MinimalAppDelegate : NSObject
{

NSTimer* timer;
UIWindow* window;
GLView* glview;
GLfloat* points;
EAGLContext* context;

float angleA;
float angleB;

}

- ( void ) update;
@end

Go back to MinimalAppDelegate implementation. We have to remove the drawing part from the bottom of applicationDidFinishLaunching method. We have to setup movement variables and the timer there instead.

angleA = ( float ) rand( ) / RAND_MAX * M_PI * 2;
angleB = ( float ) rand( ) / RAND_MAX * M_PI * 2;

points = malloc( sizeof( GLfloat ) * 4 );

points[ 0 ] = ( GLfloat ) rand( ) / RAND_MAX * 320;
points[ 1 ] = ( GLfloat ) rand( ) / RAND_MAX * 480;
points[ 2 ] = ( GLfloat ) rand( ) / RAND_MAX * 320;
points[ 3 ] = ( GLfloat ) rand( ) / RAND_MAX * 480;

// START TIMER

timer = [ NSTimer
scheduledTimerWithTimeInterval : ( NSTimeInterval ) 1.0 / 20.0
target : self
selector : @selector ( update )
userInfo : nil
repeats : YES ];


We have to move the drawing part to a separate function, which will be called by our NSTimer simultaneously. This will be "update".

First we need to refresh particle positions.

// modify direction

angleA += -.5 + ( float ) rand( ) / RAND_MAX * 1;
angleB += -.5 + ( float ) rand( ) / RAND_MAX * 1;

// update position

points[ 0 ] += sin( angleA ) * 10;
points[ 1 ] += cos( angleA ) * 10;
points[ 2 ] += sin( angleB ) * 10;
points[ 3 ] += cos( angleB ) * 10;

// check borders

if ( points[0] > 320 || points[0] < 0 || points[1]> 480 || points[1] < 0 ) angleA -= M_PI;
if ( points[2] > 320 || points[2] < 0 || points[3]> 480 || points[3] < 0 ) angleB -= M_PI;


Then let's move the texture sprite drawing code below

// enable texturing

glEnable( GL_TEXTURE_2D );

// assig vertex pointer

glVertexPointer( 2 , GL_FLOAT , 0 , points );

// set point size

glPointSize( 150 );

// draw vertexes

glDrawArrays( GL_POINTS , 0 , 2 );


Then, to make things more spectacular, we darken the whole scene, and we get a nice "glowing trail" effect. We will draw a simple square with the help of a triangle strip, we will use vertex coloring, so we have to switch off textures, and enable color array access.

The last part is :

// disable texturing

glDisable( GL_TEXTURE_2D );

// enable color array for writing

glEnableClientState( GL_COLOR_ARRAY );

// define screen sized square with transparency

GLfloat square [ ] = { 0 , 0 , 0 , 480 , 320 , 0 , 320 , 480 };
GLubyte colors [ ] = { 0 , 0 , 0 , 200 , 0 , 0 , 0 , 200 , 0 , 0 , 0 , 200 , 0 , 0 , 0 , 200 };

// assign vertex and color pointer

glVertexPointer( 2 , GL_FLOAT , 0 , square );
glColorPointer( 4 , GL_UNSIGNED_BYTE , 0 , colors );

// draw

glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 );

// disable color array before using texture

glDisableClientState( GL_COLOR_ARRAY );

// display renderbuffer content

[ context presentRenderbuffer : GL_RENDERBUFFER_OES ];


If you move the darkening part before the sprite drawing, you get brighter glows, check it in the source.

Download source.


powered by kure