Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OpenGL ES with iOS 5 - Part 1: Learning to draw

Chris Miles
September 06, 2012

OpenGL ES with iOS 5 - Part 1: Learning to draw

The first of two OpenGL ES with iOS talks I gave at Swipe Conference 2012 in Sydney, Australia.

This talk provides an introduction to OpenGL and GLKit.

Watch the presentation video at:

Read more at:

Also see part 2:

Chris Miles

September 06, 2012

More Decks by Chris Miles

Other Decks in Programming


  1. SWIPE CONFERENCE 2012 @chrismiles OpenGL ES Open standard for 2D

    & 3D graphics programming Hardware accelerated by GPU Cross platform C-based API ES: Embedded Systems variant OpenGL ES 1.1 and 2.0 2
  2. SWIPE CONFERENCE 2012 @chrismiles GLKit Framework added to iOS 5

    Helps simplify OpenGL ES integration GLKViewController, GLKView GLKBaseEffect GLKMath 3
  3. SWIPE CONFERENCE 2012 @chrismiles - (void)viewDidLoad { [super viewDidLoad]; self.context

    = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; GLKView *view = (GLKView *)self.view; view.context = self.context; view.drawableDepthFormat = GLKViewDrawableDepthFormat24; self.preferredFramesPerSecond = 60; [self setupGL]; } 7
  4. SWIPE CONFERENCE 2012 @chrismiles #pragma mark - GLKViewController frame update

    - (void)update { // Update frame data: transforms, physics, vertex animations, etc } #pragma mark - GLKViewDelegate methods - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { // Draw frame using OpenGL ES } 8
  5. SWIPE CONFERENCE 2012 @chrismiles GLKViewController Implements an OpenGL ES rendering

    loop Automatically pause when inactive or backgrounded Recommended way to support device rotation Works with a GLKView 9
  6. SWIPE CONFERENCE 2012 @chrismiles GLKView Creates and manages an OpenGL

    ES framebuffer object Draw by overriding drawRect: or by assigning a delegate object Supports colour, depth & stencil buffers Supports 4x multisampling 10
  7. SWIPE CONFERENCE 2012 @chrismiles #define kNumVertices 24 static GLfloat gTrianglesBoxVertexData[kNumVertices*3]

    = { // position x, position y, position z // Front -0.5f, -0.5f, 0.5f, // 1 0.5f, 0.5f, 0.5f, // 2 -0.5f, 0.5f, 0.5f, // 3 -0.5f, -0.5f, 0.5f, // 1 0.5f, -0.5f, 0.5f, // 4 0.5f, 0.5f, 0.5f, // 2 . . . }; 14
  8. SWIPE CONFERENCE 2012 @chrismiles glGenVertexArraysOES(1, &_trianglesVertexArray); glBindVertexArrayOES(_trianglesVertexArray); glGenBuffers(1, &_trianglesVertexBuffer); glBindBuffer(GL_ARRAY_BUFFER,

    _trianglesVertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*kNumVertices*3, _vertexData, GL_DYNAMIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (char *)0); Vertex Array Object (VAO) ➔Vertex data configuration Vertex Buffer Object (VBO) ➔Vertex data buffer Position vertex attribute ➔Enable and configure 15
  9. SWIPE CONFERENCE 2012 @chrismiles Vertex Array Object Encapsulates vertex data

    configuration OpenGL driver can optimise for the saved state glGenVertexArraysOES() glBindVertexArrayOES() 16
  10. SWIPE CONFERENCE 2012 @chrismiles Vertex Buffer Object Stores vertex data

    in GPU memory Avoids copying vertex data for every frame glGenBuffers() glBindBuffer() glBufferData() 17
  11. SWIPE CONFERENCE 2012 @chrismiles Vertex Attribute Configuration Enable an attribute

    with glEnableVertexAttribArray() Configure attribute data with glVertexAttribPointer() Use attribute indices provided by GLKit: GLKVertexAttribPosition GLKVertexAttribNormal GLKVertexAttribColor GLKVertexAttribTexCoord0 18
  12. SWIPE CONFERENCE 2012 @chrismiles - (void)setupGL { self.effect = [[GLKBaseEffect

    alloc] init]; } - (void)update { self.effect.transform.projectionMatrix = projectionMatrix; self.effect.transform.modelviewMatrix = modelViewMatrix; } GLKBaseEffect 21
  13. SWIPE CONFERENCE 2012 @chrismiles - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClearColor(0.0f,

    0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); [self.effect prepareToDraw]; glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*kNumVertices*3, _vertexData, GL_DYNAMIC_DRAW); glDrawArrays(GL_TRIANGLES, 0, kNumVertices); } Clear colour & depth buffers Enable GLKBaseEffect shader Start rendering Update vertex data 22
  14. SWIPE CONFERENCE 2012 @chrismiles GLKBaseEffect Takes care of rendering effects

    By writing shaders for us Handles: projection & model transforms, vertex colours, texturing, lighting and fog Replicates OpenGL ES 1.1 effects 23
  15. SWIPE CONFERENCE 2012 @chrismiles self.effect = [[GLKBaseEffect alloc] init]; self.effect.constantColor

    = GLKVector4Make(1.0f, 1.0f, 0.0f, 1.0f); // yellow self.effect.useConstantColor = YES; glEnableVertexAttribArray(GLKVertexAttribColor); Use vertex colours Use constant colour across all vertices OR 26
  16. SWIPE CONFERENCE 2012 @chrismiles Interleaved Vertex Array (IVA) {x, y,

    z, r, g, b, a, x, y, z, r, g, b, a, x, y, z, r, g, b, a} Vertex 1 Vertex 2 Vertex 3 Position (3 floats) Colour (4 ubytes) 27 • Offset and Stride in bytes • Greatly helps with memory locality
  17. SWIPE CONFERENCE 2012 @chrismiles typedef struct _vertexStruct { GLfloat position[3];

    GLubyte color[4]; } vertexStruct; #define kBytesPerVertex (sizeof(vertexStruct)) 28
  18. SWIPE CONFERENCE 2012 @chrismiles GLsizei stride = kBytesPerVertex; glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition,

    3, GL_FLOAT, GL_FALSE, stride, (char *)offsetof(vertexStruct, position)); glEnableVertexAttribArray(GLKVertexAttribColor); glVertexAttribPointer(GLKVertexAttribColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (char *)offsetof(vertexStruct, color)); Stride = bytes per vertex IVA Offset to attribute data in bytes 29
  19. SWIPE CONFERENCE 2012 @chrismiles self.effect = [[GLKBaseEffect alloc] init]; self.effect.light0.enabled

    = GL_TRUE; self.effect.light0.ambientColor = GLKVector4Make(0.1f, 0.1f, 0.1f, 1.0f); self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f); self.effect.light0.position = GLKVector4Make(0.0f, 0.0f, 1.0f, 0.0f); self.effect.lightModelTwoSided = YES; Enable first light Configure lighting calculation properties 32 • GLKEffectPropertyLight is identical to the lighting model implemented in OpenGL ES 1.1. • W=0.0: Directional Light, infinitely far away, position is direction to the light (i.e. negative of light travel vector) • W>0.0 and spotCutoff=180.0: Point Light, emits light in all directions from specific point, can set attenuation • W>0.0 and spotCutoff<180.0: Spot Light • Ambient Light: “background” non-directional light • Diffuse Light: directional reflected light
  20. SWIPE CONFERENCE 2012 @chrismiles Surface Normals v1 v2 v3 typedef

    struct _vertexStruct { GLfloat position[3]; GLfloat normals[3]; GLubyte color[4]; } vertexStruct; 34
  21. SWIPE CONFERENCE 2012 @chrismiles Shaders Vertex Shader: Vertex calculations E.g.

    project vertices on to 2D plane Executes shader program per vertex 37
  22. SWIPE CONFERENCE 2012 @chrismiles Shaders Fragment Shader Receives interpolated values

    from vertex shader output Calculates output pixel colours Executes shader program per output pixel 38
  23. SWIPE CONFERENCE 2012 @chrismiles Summary GLKViewController & GLKView Vertex Data,

    VAOs, VBOs GLKBaseEffect Colours Lighting Shaders 41
  24. SWIPE CONFERENCE 2012 @chrismiles Part 2 Preview Advanced GLKit effects

    & texturing OpenGL ES debugging & profiling tools Performance & best practices for iOS devices Fancy segue transitions using OpenGL ES More demos! 42
  25. SWIPE CONFERENCE 2012 Chris Miles iOS Specialist Software Engineer [email protected]

    @chrismiles Thank you http://chrismiles.info/ https://github.com/chrismiles/SwipeOpenGLTriangles 44