title: openGL ES 1.0 incompatibility on 4th gen ipod Tocuh
body: <p>Just found out my app is just displaying a black screen on the 4th gen ipod touch. It has worked on most other apple devices ive tested such as the iphone 3gs which work fine. Here is my boilerplate code that generates my GLView, anyone know what could be the problem? Or of a more modern boilerplate to use for opengl es 1.0?</p>
  
  <p>GLView.m:</p>
  
  <pre><code>//
  //  GLView.m
  //  Part6Project
  //
  //  Created by jeff on 5/31/09.
  //  Copyright Jeff LaMarche 2009. All rights reserved.
  //
  
  #import &lt;QuartzCore/QuartzCore.h&gt;
  #import &lt;OpenGLES/EAGLDrawable.h&gt;
  #import "GLView.h"
  #import "GLViewController.h"
  
  @interface GLView (private)
  
  - (id)initGLES;
  - (BOOL)createFramebuffer;
  - (void)destroyFramebuffer;
  
  @end
  
  @implementation GLView
  
  @synthesize animationInterval;
  + (Class) layerClass
  {
      return [CAEAGLLayer class];
  }
  -(id)initWithFrame:(CGRect)frame
  {
      self = [super initWithFrame:frame];
      if(self != nil)
      {
          self = [self initGLES];
      }
      return self;
  }
  
  - (id)initWithCoder:(NSCoder*)coder
  {
      if((self = [super initWithCoder:coder]))
      {
          self = [self initGLES];
      }   
      return self;
  }
  
  -(id)initGLES
  {
      NSLog(@"created");
      CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer;
  
      if ([self respondsToSelector:@selector(contentScaleFactor)])
      {
          self.contentScaleFactor = [[UIScreen mainScreen] scale]; 
          // scale value should be 1.0 on 3G and 3GS, and 2.0 on iPhone 4.
          self.contentMode = UIViewContentModeScaleToFill;
      }
  
      // Configure it so that it is opaque, does not retain the contents of the backbuffer when displayed, and uses RGBA8888 color.
      eaglLayer.opaque = YES;
      eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
                                      kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
                                      nil];
  
      // Create our EAGLContext, and if successful make it current and create our framebuffer.
      context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
      if(!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer])
      {
  //      [self release];
          return nil;
      }
  
      // Default the animation interval to 1/60th of a second.
      animationInterval = 1.0 / kRenderingFrequency;
      return self;
  }
  
  -(GLViewController *)controller
  {
      return controller;
  }
  
  -(void)setController:(GLViewController *)d
  {
      controller = d;
      controllerSetup = ![controller respondsToSelector:@selector(setupView:)];
  }
  
  // If our view is resized, we'll be asked to layout subviews.
  // This is the perfect opportunity to also update the framebuffer so that it is
  // the same size as our display area.
  -(void)layoutSubviews
  {
  
      [EAGLContext setCurrentContext:context];
      [self destroyFramebuffer];
      [self createFramebuffer];
      [self drawView];
  }
  
  - (BOOL)createFramebuffer
  {
          // Generate IDs for a framebuffer object and a color renderbuffer
      glGenFramebuffersOES(1, &amp;viewFramebuffer);
      glGenRenderbuffersOES(1, &amp;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&lt;EAGLDrawable&gt;)self.layer];
      glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
  
      glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &amp;backingWidth);
      glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &amp;backingHeight);
  
      // For this sample, we also need a depth buffer, so we'll create and attach one via another renderbuffer.
      glGenRenderbuffersOES(1, &amp;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;
  }
  
  // Clean up any buffers we have allocated.
  - (void)destroyFramebuffer
  {
      glDeleteFramebuffersOES(1, &amp;viewFramebuffer);
      viewFramebuffer = 0;
      glDeleteRenderbuffersOES(1, &amp;viewRenderbuffer);
      viewRenderbuffer = 0;
  
      if(depthRenderbuffer)
      {
          glDeleteRenderbuffersOES(1, &amp;depthRenderbuffer);
          depthRenderbuffer = 0;
      }
  }
  
  - (void)startAnimation
  {
      animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
  }
  
  - (void)stopAnimation
  {
      [animationTimer invalidate];
      animationTimer = nil;
  }
  
  - (void)setAnimationInterval:(NSTimeInterval)interval
  {
      animationInterval = interval;
  
      if(animationTimer)
      {
          [self stopAnimation];
          [self startAnimation];
      }
  }
  
  // Updates the OpenGL view when the timer fires
  - (void)drawView
  {
      // Make sure that you are drawing to the current context
      [EAGLContext setCurrentContext:context];
  
      // If our drawing delegate needs to have the view setup, then call -setupView: and flag that it won't need to be called again.
      if(!controllerSetup)
      {
          [controller setupView:self];
          controllerSetup = YES;
      }
  
      glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
  
      [controller drawView:self];
  
      glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
      [context presentRenderbuffer:GL_RENDERBUFFER_OES];
  
      GLenum err = glGetError();
      if(err)
          NSLog(@"%x error", err);
  }
  
  // Stop animating and release resources when they are no longer needed.
  - (void)dealloc
  {
      [self stopAnimation];
  
      if([EAGLContext currentContext] == context)
      {
          [EAGLContext setCurrentContext:nil];
      }
  
      context = nil;
  
  }
  
  @end
  </code></pre>
  
  <p>GLView.h:</p>
  
  <pre><code>//
  //  GLView.h
  //  Part6Project
  //
  //  Created by jeff on 5/31/09.
  //  Copyright Jeff LaMarche 2009. All rights reserved.
  //
  
  #import &lt;UIKit/UIKit.h&gt;
  #import &lt;OpenGLES/EAGL.h&gt;
  #import &lt;OpenGLES/ES1/gl.h&gt;
  #import &lt;OpenGLES/ES1/glext.h&gt;
  #import "ConstantsAndMacros.h"
  #import "OpenGLCommon.h"
  @class GLViewController;
  @interface GLView : UIView
  {
  @private
      // The pixel dimensions of the backbuffer
      GLint backingWidth;
      GLint backingHeight;
  
      EAGLContext *context;
      GLuint viewRenderbuffer, viewFramebuffer;
      GLuint depthRenderbuffer;
      NSTimer *animationTimer;
      NSTimeInterval animationInterval;
  
      GLViewController *controller;
      BOOL controllerSetup;
  }
  
  @property(nonatomic, weak) GLViewController *controller;
  @property NSTimeInterval animationInterval;
  
  -(void)startAnimation;
  -(void)stopAnimation;
  -(void)drawView;
  
  @end
  </code></pre>