// // EAGLView.m // GL-Sprite // // Created by angel on 28/03/09. // Copyright ofcode.com 2009. All rights reserved. // #import #import #import "EAGLView.h" #import "GL.h" #define USE_DEPTH_BUFFER 0 // A class extension to declare private methods @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; // You must implement this method + (Class)layerClass { return [CAEAGLLayer class]; } //The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: - (id)initWithCoder:(NSCoder*)coder { if ((self = [super initWithCoder:coder])) { // Get the layer CAEAGLLayer *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 || ![EAGLContext setCurrentContext:context]) { [self release]; return nil; } animationInterval = 1.0 / 60.0; } return self; } -(void)inicializar { // Cargamos la unica textura que vamos a usar textureid = [GL loadTexture:@"4Sprites.png"]; // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); } - (void)setupView { // Sets up matrices and transforms for OpenGL ES glViewport(0, 0, backingWidth, backingHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrthof(-160.0f, 160.0f, 240.0f,-240.0f, -1.0f, 1.0f); // center <0,0,0> on screen glMatrixMode(GL_MODELVIEW); // Clears the view with black glClearColor(0.0f, 0.0f, 0.0f, 1.0f); } -(void)clearBuffer { [EAGLContext setCurrentContext:context]; glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); glClear(GL_COLOR_BUFFER_BIT); } -(void)swapBuffer { glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); [context presentRenderbuffer:GL_RENDERBUFFER_OES]; } - (void)drawView { static int angle = 0; angle+=3; [self clearBuffer]; glLoadIdentity(); glPushMatrix(); [GL setSprite:textureid frame:0]; glRotatef(angle,0,0,1); glTranslatef(-80,-80,0); glRotatef(-angle,0,0,1); [GL drawSprite:-64 y1:-64 x2:64 y2:64]; glPopMatrix(); glPushMatrix(); [GL setSprite:textureid frame:1]; glRotatef(angle,0,0,1); glTranslatef( 80,-80,0); glRotatef(-angle,0,0,1); [GL drawSprite:-64 y1:-64 x2:64 y2:64]; glPopMatrix(); glPushMatrix(); [GL setSprite:textureid frame:2]; glRotatef(angle,0,0,1); glTranslatef(-80, 80,0); glRotatef(-angle,0,0,1); [GL drawSprite:-64 y1:-64 x2:64 y2:64]; glPopMatrix(); glPushMatrix(); [GL setSprite:textureid frame:3]; glRotatef(angle,0,0,1); glTranslatef( 80, 80,0); glRotatef(-angle,0,0,1); [GL drawSprite:-64 y1:-64 x2:64 y2:64]; glPopMatrix(); [self swapBuffer]; } - (void)layoutSubviews { [EAGLContext setCurrentContext:context]; [self destroyFramebuffer]; [self createFramebuffer]; [self inicializar]; // aqui cargaremos la textura [self setupView]; // aqui configuramos la camara en 2D [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); if (USE_DEPTH_BUFFER) { 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) { 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) { [self stopAnimation]; [self startAnimation]; } } - (void)dealloc { [self stopAnimation]; if ([EAGLContext currentContext] == context) { [EAGLContext setCurrentContext:nil]; } [context release]; [super dealloc]; } @end