// // EAGLView.m // Box-1 // // Created by angel on 22/03/09. // Copyright __MyCompanyName__ 2009. All rights reserved. // #import #import #import "EAGLView.h" #define USE_DEPTH_BUFFER 1 // 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; #define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__) / 180.0 * M_PI) #define RANDOM_SEED() srandom(time(NULL)) #define RANDOM_INT(__MIN__, __MAX__) ((__MIN__) + random() % ((__MAX__+1) - (__MIN__))) // 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 { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glEnable(GL_TEXTURE_2D); // Activamos el Blend glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // Activamos el Cull Face glEnable(GL_CULL_FACE); glFrontFace(GL_CW); // Activamos el DepthTest glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); // Ponemos una luz GLfloat lightPosition1[] = { 10.0f, 10.0f, -10.0f, 1.0f }; GLfloat lightDiffuse1[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat lightAmbient1[] = { 0.4f, 0.4f, 0.8f, 1.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient1); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse1); glLightfv(GL_LIGHT0, GL_POSITION, lightPosition1); glEnable(GL_LIGHT0 ); glEnable(GL_LIGHTING); for(int i=0;i<7;i++) box[i] = [Box alloc]; [box[0] init: 0 y: 0 z: 0]; // Centro [box[1] init: 1 y: 0 z: 0]; // x = 1 [box[2] init:-1 y: 0 z: 0]; // x = -1 [box[3] init: 0 y: 1 z: 0]; // y = 1 [box[4] init: 0 y:-1 z: 0]; // y = -1 [box[5] init: 0 y: 0 z: 1]; // z = 1 [box[6] init: 0 y: 0 z:-1]; // z = -1 // Cargamos la textura texture = [GL loadTexture:"Box.png"]; } - (void)setupView { GLfloat zNear = 0.1, zFar = 1000.0, fieldOfView = 40.0; GLfloat size; GLfloat width = 320; GLfloat height = 480; //Set the OpenGL projection matrix glMatrixMode(GL_PROJECTION); size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0); //CGRect rect = view.bounds; glFrustumf(-size, size, size / (width / height), - size / (width / height), zNear, zFar); glViewport(0, 0, width, height); //Make the OpenGL modelview matrix the default glMatrixMode(GL_MODELVIEW); // Clears the view with black //glClearColor(0.25f, 0.25f, 0.25f, 1.0f); } -(void)clearBuffer { [EAGLContext setCurrentContext:context]; glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); glClear(GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT); } -(void)swapBuffer { glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); [context presentRenderbuffer:GL_RENDERBUFFER_OES]; } // Updates the OpenGL view when the timer fires - (void)drawView { static GLfloat anglex = 0.0f; anglex+=0.6f; static GLfloat angley = 0.0f; angley+=0.5f; static GLfloat anglez = 0.0f; anglez+=0.3f; [self clearBuffer]; glLoadIdentity(); glTranslatef(0,0,-8); glRotatef(anglex, 1, 0, 0); glRotatef(angley, 0, 1, 0); glRotatef(anglez, 0, 0, 1); // Activamos la textura glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); [box[0] Render]; [box[1] Render]; [box[2] Render]; [box[3] Render]; [box[4] Render]; [box[5] Render]; [box[6] Render]; [self swapBuffer]; } - (void)layoutSubviews { [EAGLContext setCurrentContext:context]; [self destroyFramebuffer]; [self createFramebuffer]; [self inicializar]; [self setupView]; [self drawView]; } - (BOOL)createFramebuffer { // Generate IDs for a framebuffer object and a color renderbuffer glGenFramebuffersOES(1, &viewFramebuffer); glGenRenderbuffersOES(1, &viewRenderbuffer); glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); // This call associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer) // allowing us to draw into a buffer that will later be rendered to screen whereever the layer is (which corresponds with our view). [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id)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); // For this sample, we also need a depth buffer, so we'll create and attach one via another renderbuffer. 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