CS185c
Chris Pollett
Nov. 18, 2009
[glView startAnimation];in appDidFinishLaunching
renderer = [[ES2Renderer alloc] init];
- (void) startAnimation { if (!animating) { if (displayLinkSupported) { // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will // not be called in system versions earlier than 3.1. displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)]; [displayLink setFrameInterval:animationFrameInterval]; [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } else animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE]; animating = TRUE; } }
- (void) drawView:(id)sender { [renderer render]; }
// Create an ES 2.0 context - (id) init { if (self = [super init]) { context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; if (!context || ![EAGLContext setCurrentContext:context] || ![self loadShaders]) { [self release]; return nil; } // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer glGenFramebuffers(1, &defaultFramebuffer); glGenRenderbuffers(1, &colorRenderbuffer); glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); } return self; }
The code to render things should look reasonably familiar if you followed the Android examples...
- (void) render { // Replace the implementation of this method to do your own custom drawing static const GLfloat squareVertices[] = { -0.5f, -0.33f, 0.5f, -0.33f, -0.5f, 0.33f, 0.5f, 0.33f, }; static const GLubyte squareColors[] = { 255, 255, 0, 255, 0, 255, 255, 255, 0, 0, 0, 0, 255, 0, 255, 255, }; static float transY = 0.0f; // This application only creates a single context which is already set current at this point. // This call is redundant, but needed if dealing with multiple contexts. [EAGLContext setCurrentContext:context]; // This application only creates a single default framebuffer which is already bound at this point. // This call is redundant, but needed if dealing with multiple framebuffers. glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); glViewport(0, 0, backingWidth, backingHeight); glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Use shader program glUseProgram(program); // Update uniform value glUniform1f(uniforms[UNIFORM_TRANSLATE], (GLfloat)transY); transY += 0.075f; // Update attribute values glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); glEnableVertexAttribArray(ATTRIB_VERTEX); glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, 1, 0, squareColors); glEnableVertexAttribArray(ATTRIB_COLOR); // Validate program before drawing. This is a good check, but only really necessary in a debug build. // DEBUG macro must be defined in your debug configurations if that's not already the case. #if defined(DEBUG) if (![self validateProgram:program]) { NSLog(@"Failed to validate program: %d", program); return; } #endif // Draw glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // This application only creates a single color renderbuffer which is already bound at this point. // This call is redundant, but needed if dealing with multiple renderbuffers. glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); [context presentRenderbuffer:GL_RENDERBUFFER]; }
glViewport(0, 0, backingWidth, backingHeight);corresponds to the code we had in our Android application
gl.glViewport(0, 0, view.getWidth(), view.getHeight());
static const GLfloat cube[] = { -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f }; static const GLfloat colors[] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f };
static const GLubyte triangles [] = { 1, 0, 2, 3, 2, 0, 6, 4, 5, 4, 6, 7, 4, 7, 0, 7, 3, 0, 1, 2, 5, 2, 6, 5, 0, 1, 5, 0, 5, 4, 2, 3, 6, 3, 7, 6 };
glVertexPointer(3, GL_FLOAT, 0, cube); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, triangles);