title: OpenGl ES 2.0 and GLKit : From GLKBaseEffect shaders to OpenGl
body: <p>I'm coding a 2D game with OpenGL ES 2.0 and GLKit. My architecture is based on the Games by Ian Terrel tutorials.</p>
  
  <p>I discover recently that the GLKBaseEffect (provide simple shaders mgmt) leaks and makes sometimes my app crash. I'm now using my own shaders files (based on the Ray Wenderlich tutorial) but, at this time, I've just succeed to display openGl background color. My shapes colors and textures aren't displayed anymore.</p>
  
  <p><strong>IMPORTANT</strong> : I was setting the current context badly, now openGL says invalid Drawable. </p>
  
  <p>Here is a part of my shape.m code :</p>
  
  <pre><code>@implementation P3Shape
  
  const GLushort indices[] = {
      0,1,2,3
  };
  
  typedef struct {
      float Position[2];
      float Color[4];
      float TexCoord[2];
  } Vertex;
  
  //testing
  const Vertex Vertices[] = {
      // Front
      {{10, -15}, {1, 0, 0, 1}, {1, 0}},
      {{10, 15}, {0, 1, 0, 1}, {1, 0}},
      {{-10, 10}, {0, 0, 1, 1}, {0, 0}},
      {{-10, -1}, {0, 0, 0, 1}, {0, 1}},
  };
  
  - (id)initWithLayer:(CAEAGLLayer *)layer {
      self = [super init];
      if (self) {
          [...]
          _currentContext = [P3SessionState currentContext];
          _eaglLayer = layer;
          _eaglLayer.opaque = YES;
          [self setupRenderBuffer];        
          [self setupFrameBuffer]; 
          [self addToProgram];
          [self createBuffers];
      }
      return self;
  }
  
  
  - (int)numVertices {
      return 0;
  }
  
  - (void) addToProgram {
      // setted before in the gamemanager
      GLuint programHandle = [P3SessionState programHandle];
  
      _positionSlot = glGetAttribLocation(programHandle, "Position");
      _colorSlot = glGetAttribLocation(programHandle, "SourceColor");
  
      _projectionUniform = glGetUniformLocation(programHandle, "Projection");
      _modelViewUniform = glGetUniformLocation(programHandle, "Modelview");
  
      _texCoordSlot = glGetAttribLocation(programHandle, "TexCoordIn");
      _textureUniform = glGetUniformLocation(programHandle, "Texture");
  }
  
  - (void)setupRenderBuffer {
      glGenRenderbuffers(1, &amp;_colorRenderBuffer);
      glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);        
      [_currentContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];    
  }
  
  - (void)setupFrameBuffer {    
      GLuint framebuffer;
      glGenFramebuffers(1, &amp;framebuffer);
      glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);   
      glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer);
      glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
  }
  
  - (void)createBuffers {
      // Static index data
      glGenBuffers(1, &amp;indexBuffer);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
  
      glGenBuffers(1, &amp;vertexBuffer);
      glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
      glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
  }
  
  // initialize the vertex data
  
  - (GLKVector2 *)vertices {
      if (vertexData == nil) {
          vertexData = [NSMutableData dataWithLength:sizeof(GLKVector2)*self.numVertices];
      }
      return [vertexData mutableBytes];
  }
  
  // set a textureImage, allocate a glname and enable the GL_TEXTURE_2D and all
  - (void)setTextureImage:(UIImage *)image {
      CGImageRef spriteImage = image.CGImage;
      if (!spriteImage) {
          NSLog(@"Failed to load image %@", image);
          exit(1);
      }
  
      size_t width = CGImageGetWidth(spriteImage);
      size_t height = CGImageGetHeight(spriteImage);
  
      GLubyte * spriteData = (GLubyte *) calloc(width*height*4, sizeof(GLubyte));
  
      CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);    
  
      CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
  
      CGContextRelease(spriteContext);
  
      GLuint texName;
      glGenTextures(1, &amp;texName);
      glBindTexture(GL_TEXTURE_2D, texName);
  
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
  
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
  
      free(spriteData);        
      _imageTexture = texName;
  }    
  
  - (GLKVector2 *)textureCoordinates {
      if (textureCoordinateData == nil)
          textureCoordinateData = [NSMutableData dataWithLength:sizeof(GLKVector2)*self.numVertices];
      return [textureCoordinateData mutableBytes];
  }
  
  
  - (void)render {
  
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  
      glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
      glUniformMatrix4fv(_modelViewUniform, 1, 0, modelview.m);
      glUniformMatrix4fv(_projectionUniform, 1, 0, projectionMatrix.m);
  
      glEnableVertexAttribArray(_positionSlot);
  
      glEnableVertexAttribArray(_colorSlot);
      glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
  
      glVertexAttribPointer(_positionSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
      glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
      if(texture != nil) {
          glEnableVertexAttribArray(_texCoordSlot);
          glActiveTexture(GL_TEXTURE0); // unneccc in practice
          glBindTexture(GL_TEXTURE_2D, _imageTexture);
          glUniform1i(_textureUniform, 0); // unnecc in practice
          glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7));
      }
  
          glDrawElements(GL_TRIANGLE_FAN, sizeof(indices)/sizeof(GLushort), GL_UNSIGNED_SHORT, (void*)0);
      }
      //is cleanup code that tells the shader that we’re done using vertex position data.
      glDisableVertexAttribArray(GLKVertexAttribPosition);
  
      if (texture != nil)
          glDisableVertexAttribArray(GLKVertexAttribTexCoord0);
  
      [_currentContext presentRenderbuffer:GL_RENDERBUFFER];
  
      glDisable(GL_BLEND);
  }
  
  // draw the shape in the selected scene
  - (void)renderInScene:(P3Scene *)theScene {
  
      projectionMatrix = [theScene projectionMatrix];
  
      modelview = GLKMatrix4Multiply(GLKMatrix4MakeTranslation(0, 0, 0), GLKMatrix4MakeRotation(0, 0, 0, 1));
      modelview = GLKMatrix4Multiply(modelview, GLKMatrix4MakeScale(scale.x, scale.y, 1));
  
      [self render];
  }
  
  -(void)update:(NSTimeInterval)dt {
      if(self.toDraw)
          [spriteAnimation update:dt];
  }
  
  @end
  </code></pre>
  
  <p>As you can see, I'm testing with a Vertices array and a basic color but it makes no differences. OpenGl seems to be set correctly because my view is green thanks to the <em>glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);</em> in the render function.</p>
  
  <p>Here the files on pastebin :</p>
  
  <p><a href="http://pastebin.com/QymUWQef" rel="nofollow">P3Shape.m on pastebin</a></p>
  
  <p>And a manager who create the ogl program</p>
  
  <p><a href="http://pastebin.com/3n5iwYy2" rel="nofollow">P3GameManager.m on pastebin</a></p>
  
  <p>Any ideas ?</p>
  
  <p>EDIT : maybe a problem with my shaders ?</p>
  
  <p>vertex :</p>
  
  <pre><code>attribute vec4 Position; 
  attribute vec4 SourceColor; 
  
  varying vec4 DestinationColor; 
  
  uniform mat4 Projection;
  uniform mat4 Modelview;
  
  attribute vec2 TexCoordIn; // New
  varying vec2 TexCoordOut; // New
  
  void main(void) { 
      DestinationColor = SourceColor; 
      gl_Position = Projection * Modelview * Position;
      TexCoordOut = TexCoordIn; // New
  }
  </code></pre>
  
  <p>and fragment :</p>
  
  <pre><code>varying lowp vec4 DestinationColor;
  
  varying lowp vec2 TexCoordOut; // New
  uniform sampler2D Texture; // New
  
  void main(void) {
      gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut); // New
  }
  </code></pre>