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:
https://www.youtube.com/watch?v=s6VCaFQFBtM

Read more at:
http://blog.chrismiles.info/2012/10/opengl-es-with-ios-5-part-1-learning-to.html

Also see part 2:
https://speakerdeck.com/chrismiles/opengl-es-with-ios-5-part-2-rendering-a-masterpiece

Chris Miles

September 06, 2012
Tweet

More Decks by Chris Miles

Other Decks in Programming

Transcript

  1. @chrismiles
    http://chrismiles.info/
    Chris Miles
    OpenGL ES with iOS 5
    Part 1: Learning to draw
    1

    View Slide

  2. 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

    View Slide

  3. SWIPE CONFERENCE 2012
    @chrismiles
    GLKit
    Framework added to iOS 5
    Helps simplify OpenGL ES integration
    GLKViewController, GLKView
    GLKBaseEffect
    GLKMath
    3

    View Slide

  4. SWIPE CONFERENCE 2012
    @chrismiles
    Our Goal
    Learn enough to understand the “OpenGL Game” template project
    4

    View Slide

  5. SWIPE CONFERENCE 2012
    @chrismiles
    GLKViewController
    GLKView
    5

    View Slide

  6. SWIPE CONFERENCE 2012
    @chrismiles
    #import
    @interface OGDTrianglesViewController : GLKViewController
    @end
    6

    View Slide

  7. 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

    View Slide

  8. 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

    View Slide

  9. 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

    View Slide

  10. 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

    View Slide

  11. SWIPE CONFERENCE 2012
    @chrismiles
    Vertex Data
    11

    View Slide

  12. SWIPE CONFERENCE 2012
    @chrismiles
    OpenGLESDrawing
    GL_TRIANGLES
    12

    View Slide

  13. SWIPE CONFERENCE 2012
    @chrismiles
    1
    2
    3
    4
    1
    2
    1
    2
    3
    4 5
    6
    13

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

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

    View Slide

  17. SWIPE CONFERENCE 2012
    @chrismiles
    Vertex Buffer Object
    Stores vertex data in GPU memory
    Avoids copying vertex data for every frame
    glGenBuffers()
    glBindBuffer()
    glBufferData()
    17

    View Slide

  18. 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

    View Slide

  19. SWIPE CONFERENCE 2012
    @chrismiles
    GLKBaseEffect
    19

    View Slide

  20. SWIPE CONFERENCE 2012
    @chrismiles
    OpenGLESDrawing
    GL_TRIANGLES
    20

    View Slide

  21. 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

    View Slide

  22. 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

    View Slide

  23. 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

    View Slide

  24. SWIPE CONFERENCE 2012
    @chrismiles
    Vertex Colours
    24

    View Slide

  25. SWIPE CONFERENCE 2012
    @chrismiles
    OpenGLESDrawing
    GL_TRIANGLES Coloured
    25

    View Slide

  26. 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

    View Slide

  27. 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

    View Slide

  28. SWIPE CONFERENCE 2012
    @chrismiles
    typedef struct _vertexStruct
    {
    GLfloat position[3];
    GLubyte color[4];
    } vertexStruct;
    #define kBytesPerVertex (sizeof(vertexStruct))
    28

    View Slide

  29. 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

    View Slide

  30. SWIPE CONFERENCE 2012
    @chrismiles
    Lighting
    30

    View Slide

  31. SWIPE CONFERENCE 2012
    @chrismiles
    OpenGLESDrawing
    GL_TRIANGLES with Lighting
    31

    View Slide

  32. 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

    View Slide

  33. SWIPE CONFERENCE 2012
    @chrismiles
    Reflected Light
    Surface
    Normal
    33

    View Slide

  34. SWIPE CONFERENCE 2012
    @chrismiles
    Surface Normals
    v1
    v2
    v3
    typedef struct _vertexStruct
    {
    GLfloat position[3];
    GLfloat normals[3];
    GLubyte color[4];
    } vertexStruct;
    34

    View Slide

  35. SWIPE CONFERENCE 2012
    @chrismiles
    Shaders
    35

    View Slide

  36. SWIPE CONFERENCE 2012
    @chrismiles
    Vertex
    Shader
    Fragment
    Shader
    Linear
    Interpolation
    Vertex
    attributes
    Varyings
    Uniforms
    36

    View Slide

  37. SWIPE CONFERENCE 2012
    @chrismiles
    Shaders
    Vertex Shader:
    Vertex calculations
    E.g. project vertices on to 2D plane
    Executes shader program per vertex
    37

    View Slide

  38. 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

    View Slide

  39. SWIPE CONFERENCE 2012
    @chrismiles
    39

    View Slide

  40. SWIPE CONFERENCE 2012
    @chrismiles
    40

    View Slide

  41. SWIPE CONFERENCE 2012
    @chrismiles
    Summary
    GLKViewController & GLKView
    Vertex Data, VAOs, VBOs
    GLKBaseEffect
    Colours
    Lighting
    Shaders
    41

    View Slide

  42. 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

    View Slide

  43. SWIPE CONFERENCE 2012
    @chrismiles
    43

    View Slide

  44. SWIPE CONFERENCE 2012
    Chris Miles
    iOS Specialist Software Engineer
    [email protected]
    @chrismiles
    Thank you
    http://chrismiles.info/
    https://github.com/chrismiles/SwipeOpenGLTriangles
    44

    View Slide