SlideShare a Scribd company logo
Practical Opengl for 2D
Game Developement
Rob Muller
Part 1 - The Nitty Gritty
Opengl ES 1.x

         source - http://www.khronos.org/opengles/2_X/
Opengl ES 2.x

         source - http://www.khronos.org/opengles/2_X/
Rotations, Translations &
   Scaling - Oh My!
Rotations and Scaling are
        about 0,0,0
      void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);

      void glScalef(GLfloat x, GLfloat y, GLfloat z);



Rotations and scaling both happen about 0,0,0
They are Commutative (if translations aren’t introduced)
Cardboard vector demo?
+Y




     +X
pick your sprite coordinates around zero so they scale
  and rotate how you like:

                              bottomJustifiedQuad[ ] =
                                           {-0.5, 1.0,
                                             0.5, 1.0,
                                            -0.5, 0.0,
centerJustifiedQuad[ ] =
                                             0.5, 0.0}
             {-0.5, 0.5,
               0.5, 0.5,
             -0.5, -0.5,
                               cornerJustifiedQuad[ ] =
              0.5, -0.5}
                                             {0.0, 1.0,
                                              1.0, 1.0,
                                              0.0, 0.0,
                                              1.0, 0.0}
+Y
centerJustifiedQuad[ ] =
             {-0.5, 0.5,
               0.5, 0.5,
             -0.5, -0.5,
              0.5, -0.5}
                   -0.5, 0.5         0.5, 0.5




                                                 +X
                   -0.5, -0.5        0.5, -0.5
+Y
centerJustifiedQuad[ ] =
        1 {-0.5, 0.5,
        2      0.5, 0.5,                           Triangle Strip!
        3 -0.5, -0.5,
        4     0.5, -0.5}
                   -0.5, 0.51        2 0.5, 0.5


                                                                     +X
                   -0.5, -0.5          0.5, -0.5
                            3        4
+Y
glScalef(2.0f, 2.0f, 1.0f);
glRotatef(90.0f, 0.0f, 0.0f, 1.0f);




                                           +X
+Y
glRotatef(90.0f, 0.0f, 0.0f, 1.0f);        communative w/o
glScalef(2.0f, 2.0f, 1.0f);                  translations




                                                         +X
+Y
glScalef(1.0f, 2.0f, 1.0f);




                                   +X
+Y
glScalef(1.0f, -2.0f, 1.0f);




                                    +X
+Y
glRotatef(360.0f, 0.0f, 0.0f, 1.0f);




                                            +X
+Y
glRotatef(-45.0f, 0.0f, 0.0f, 1.0f);
                                            it’s not actually like this...




                                                                      +X
glRotatef(-45.0f, 0.0f, 0.0f, 1.0);
                                           +Y




                                      +X
+Y



                   -0.5, 1.0        0.5, 1.0




                   -0.5, 0.0         0.5, 0.0

                                                +X
bottomJustifiedQuad[ ] =
             {-0.5, 1.0,
               0.5, 1.0,
              -0.5, 0.0,
               0.5, 0.0}
glScalef(2.0f, 2.0f, 1.0f);

Scale 2x
+Y



                     f(1.0f, 0.5f,
             glScale
             1.0f);
                    P W N ED




                                     +X
Mushrooms
  FTW!
Translation in the mix


 Translations change what 0,0,0 means to the vertices
 you provide
 CardBoard demo?
glScalef(2.0f, 2.0f, 0.0f);
                                  +Y
glTranslatef(1.0f, 1.0f, 0.0f);




                                       +X

 (your actually making the
translation go twice as far)
glTranslatef(1.0f, 1.0f, 0.0f);
                                  +Y
glScalef(2.0f, 2.0f, 0.0f);




                                       +X
+Y
glRotatef(45.0f, 0.0f, 0.0f, 1.0);        At this point I
glTranslatef(1.0f, 1.0f, 0.0f);
                                          thought huh?




                                                        +X
+Y
glRotatef(45.0f, 0.0f, 0.0f, 1.0);   +X
glRotatef(45.0f, 0.0f, 0.0f, 1.0);
                                             +X
glTranslatef(1.0f, 1.0f, 0.0f);


                +Y                   (1,1)
+Y
glTranslatef(1.0f, 1.0f, 0.0f);
glRotatef(45.0f, 0.0f, 0.0f, 1.0);




                                          +X
Demo!
  trs
What is an ID in opengl?


 an ID is usually just an integer that you get when you
 make something (textures, various buffers). These are
 then “bound” and whatever drawing you do will use the
 use the texture/buffer associated with that integer value
 until you bind something else;
Part 2 - Setup
Take a moment to think
about boiler plate code
(asking the OS for stuff)
Now think about that on
your own time with some
examples you found on the
internetz...
(fairly) universal boilerplate
GLint backingWidth;
GLint backingHeight;
GLuint defaultFramebuffer, colorRenderbuffer;

                           ...
//initialization
glGenFramebuffersOES(1, &defaultFramebuffer);
glGenRenderbuffersOES(1, &colorRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
                           ...
//this is called during a resize
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer];
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
                           ...
//free everything up
if (defaultFramebuffer)
    {
        glDeleteFramebuffersOES(1, &defaultFramebuffer);
        defaultFramebuffer = 0;
    }

    if (colorRenderbuffer)
    {
        glDeleteRenderbuffersOES(1, &colorRenderbuffer);
        colorRenderbuffer = 0;
    }
Stuff you gotta mess with...
    //boilerplate init and resize stuffz

    ...

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

	   //glOrthof(left, right, bottom, top, nearClip, farClip);	
	   //glViewport(0, 0, width, heigth);
	   //glOrthof( -320 * 0.5, 320 * 0.5, 480 * 0.5, -480 * 0.5, 0, 1000 ); //iphone-ish
                     //coordinates... rotations along z are reversed and so is positive z

	   glOrthof( -320 * 0.5, 320 * 0.5, -480 * 0.5, 480 * 0.5, 0, 1000 );	//opengl coordinates
	   glViewport(0, 0, 320, 480);
	
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
	
	   glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    ...

    //draw yo stuffz
Use a stack to reset for
    another sprite


               glPushMatrix();
 Demo:
 makeSquares
               glPopMatrix();
glEnable & glDisable
	   glEnable(GL_BLEND);
	   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
	   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	   //glBlendFunc(GL_ONE, GL_ONE); //use this for Additive

    ... //draw stuff

    glDisable(GL_BLEND);




                            Demo!
                            makeSquares
Make a picture appear
(texture boiler plate)
	 GLuint texID;

glGenTextures(1, &texID);
 glBindTexture(GL_TEXTURE_2D, texID);
 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);




 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mwidth, mheight, 0,
              GL_RGBA, GL_UNSIGNED_BYTE, imageData);
Vertices &
Texture coordinates
   GLfloat quadTexture[] = {
           0.0f, 1.0f,
           1.0f, 1.0f,
           0.0f, 0.0f,
           1.0f, 0.0f
       };	 //



   GLfloat quad[] = {
        -0.5f, 0.5f, 0.0f,
   	 	 0.5f, 0.5f, 0.0f,
        -0.5f, -0.5f, 0.0f,
   	 	 0.5f, -0.5f, 0.0f
       };
centerJustifiedQuad[ ] =        GLfloat quadTexture[ ] = {
             {-0.5, 0.5,            0.0f, 1.0f,
               0.5, 0.5,            1.0f, 1.0f,
             -0.5, -0.5,            0.0f, 0.0f,
              0.5, -0.5}            1.0f, 0.0f}


  -0.5, 0.51     2 0.5, 0.5          0, 1           1, 1




  -0.5, -0.5       0.5, -0.5
           3     4                 0, 0            0, 1
centerJustifiedQuad[ ] =        GLfloat quadTexture[ ] = {
             {-0.5, 0.5,            0.25f, 1.0f,
               0.5, 0.5,            0.75f, 1.0f,
             -0.5, -0.5,            0.25f, 0.5f,
              0.5, -0.5}            0.75f, 0.5f}


  -0.5, 0.51     2 0.5, 0.5



  -0.5, -0.5       0.5, -0.5
           3     4
centerJustifiedQuad[ ] =                       GLfloat quadTexture[ ] = {
             {-0.5, 0.5,                           0.0f, 2.0f,
               0.5, 0.5,                           2.0f, 2.0f,
             -0.5, -0.5,                           0.0f, 0.0f,
              0.5, -0.5}                           2.0f, 0.0f}


  -0.5, 0.51                 2 0.5, 0.5



  -0.5, -0.5                   0.5, -0.5
           3                 4


               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Where the $#!% hits the fan



...
glPushMatrix();
//transformations go here

glBindTexture(GL_TEXTURE_2D, texID);
glVertexPointer(3, GL_FLOAT, 0, quad);
glTexCoordPointer(2, GL_FLOAT, 0, quadTexture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glPopMatrix();
Giminy Gee
                         Willikers Batman!
                        That’s a lot of stuff
                        for one source file!




   Oh, he’s much
 more cunning than
 that... This is only
the beginning of his
                               Demo!
    genius plan                 makeSprite
Ok, but what do we do
when we have a lot of
things?
drawing is done in the order you call the draw methods
depth buffer is rarely used because games almost
always have partially transparent images

   Background

    Enemies

     Hero

     HUD
Solution: Groups
Background

 Enemies


                           Background

                            Enemies


             VS.             Hero

                             HUD


   Hero

   HUD




                   (just sort within the layers)
Discussion


Scene/Asset managers
Particle Engines
Scene graphs and/or physics engine integration
Online resources
http://nehe.gamedev.net/
http://iphonedevdepot.com/
http://www.devmaster.net/engines/
http://gpwiki.org/index.php/Game_Engines
http://en.wikipedia.org/wiki/List_of_game_engines
http://www.wotsit.org/
Q&A
+1
                M
                  us
               Po hr
                 we o o
                    r !! m
                        !!


  Ol
     ds
t h ch                       d
   e M oo                 EN
          lt            e
        AX o       TH

More Related Content

Disney Effects: Building web/mobile castle in OpenGL 2D & 3D

  • 1. Practical Opengl for 2D Game Developement Rob Muller
  • 2. Part 1 - The Nitty Gritty
  • 3. Opengl ES 1.x source - http://www.khronos.org/opengles/2_X/
  • 4. Opengl ES 2.x source - http://www.khronos.org/opengles/2_X/
  • 5. Rotations, Translations & Scaling - Oh My!
  • 6. Rotations and Scaling are about 0,0,0 void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); void glScalef(GLfloat x, GLfloat y, GLfloat z); Rotations and scaling both happen about 0,0,0 They are Commutative (if translations aren’t introduced) Cardboard vector demo?
  • 7. +Y +X
  • 8. pick your sprite coordinates around zero so they scale and rotate how you like: bottomJustifiedQuad[ ] = {-0.5, 1.0, 0.5, 1.0, -0.5, 0.0, centerJustifiedQuad[ ] = 0.5, 0.0} {-0.5, 0.5, 0.5, 0.5, -0.5, -0.5, cornerJustifiedQuad[ ] = 0.5, -0.5} {0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0}
  • 9. +Y centerJustifiedQuad[ ] = {-0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5} -0.5, 0.5 0.5, 0.5 +X -0.5, -0.5 0.5, -0.5
  • 10. +Y centerJustifiedQuad[ ] = 1 {-0.5, 0.5, 2 0.5, 0.5, Triangle Strip! 3 -0.5, -0.5, 4 0.5, -0.5} -0.5, 0.51 2 0.5, 0.5 +X -0.5, -0.5 0.5, -0.5 3 4
  • 12. +Y glRotatef(90.0f, 0.0f, 0.0f, 1.0f); communative w/o glScalef(2.0f, 2.0f, 1.0f); translations +X
  • 16. +Y glRotatef(-45.0f, 0.0f, 0.0f, 1.0f); it’s not actually like this... +X
  • 18. +Y -0.5, 1.0 0.5, 1.0 -0.5, 0.0 0.5, 0.0 +X bottomJustifiedQuad[ ] = {-0.5, 1.0, 0.5, 1.0, -0.5, 0.0, 0.5, 0.0}
  • 20. +Y f(1.0f, 0.5f, glScale 1.0f); P W N ED +X Mushrooms FTW!
  • 21. Translation in the mix Translations change what 0,0,0 means to the vertices you provide CardBoard demo?
  • 22. glScalef(2.0f, 2.0f, 0.0f); +Y glTranslatef(1.0f, 1.0f, 0.0f); +X (your actually making the translation go twice as far)
  • 23. glTranslatef(1.0f, 1.0f, 0.0f); +Y glScalef(2.0f, 2.0f, 0.0f); +X
  • 24. +Y glRotatef(45.0f, 0.0f, 0.0f, 1.0); At this point I glTranslatef(1.0f, 1.0f, 0.0f); thought huh? +X
  • 26. glRotatef(45.0f, 0.0f, 0.0f, 1.0); +X glTranslatef(1.0f, 1.0f, 0.0f); +Y (1,1)
  • 29. What is an ID in opengl? an ID is usually just an integer that you get when you make something (textures, various buffers). These are then “bound” and whatever drawing you do will use the use the texture/buffer associated with that integer value until you bind something else;
  • 30. Part 2 - Setup
  • 31. Take a moment to think about boiler plate code (asking the OS for stuff)
  • 32. Now think about that on your own time with some examples you found on the internetz...
  • 33. (fairly) universal boilerplate GLint backingWidth; GLint backingHeight; GLuint defaultFramebuffer, colorRenderbuffer; ... //initialization glGenFramebuffersOES(1, &defaultFramebuffer); glGenRenderbuffersOES(1, &colorRenderbuffer); glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer); ... //this is called during a resize glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer]; glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); ... //free everything up if (defaultFramebuffer) { glDeleteFramebuffersOES(1, &defaultFramebuffer); defaultFramebuffer = 0; } if (colorRenderbuffer) { glDeleteRenderbuffersOES(1, &colorRenderbuffer); colorRenderbuffer = 0; }
  • 34. Stuff you gotta mess with... //boilerplate init and resize stuffz ... glMatrixMode(GL_PROJECTION); glLoadIdentity(); //glOrthof(left, right, bottom, top, nearClip, farClip); //glViewport(0, 0, width, heigth); //glOrthof( -320 * 0.5, 320 * 0.5, 480 * 0.5, -480 * 0.5, 0, 1000 ); //iphone-ish //coordinates... rotations along z are reversed and so is positive z glOrthof( -320 * 0.5, 320 * 0.5, -480 * 0.5, 480 * 0.5, 0, 1000 ); //opengl coordinates glViewport(0, 0, 320, 480); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); ... //draw yo stuffz
  • 35. Use a stack to reset for another sprite glPushMatrix(); Demo: makeSquares glPopMatrix();
  • 36. glEnable & glDisable glEnable(GL_BLEND); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //glBlendFunc(GL_ONE, GL_ONE); //use this for Additive ... //draw stuff glDisable(GL_BLEND); Demo! makeSquares
  • 37. Make a picture appear (texture boiler plate) GLuint texID; glGenTextures(1, &texID); glBindTexture(GL_TEXTURE_2D, texID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mwidth, mheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
  • 38. Vertices & Texture coordinates GLfloat quadTexture[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f }; // GLfloat quad[] = { -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f };
  • 39. centerJustifiedQuad[ ] = GLfloat quadTexture[ ] = { {-0.5, 0.5, 0.0f, 1.0f, 0.5, 0.5, 1.0f, 1.0f, -0.5, -0.5, 0.0f, 0.0f, 0.5, -0.5} 1.0f, 0.0f} -0.5, 0.51 2 0.5, 0.5 0, 1 1, 1 -0.5, -0.5 0.5, -0.5 3 4 0, 0 0, 1
  • 40. centerJustifiedQuad[ ] = GLfloat quadTexture[ ] = { {-0.5, 0.5, 0.25f, 1.0f, 0.5, 0.5, 0.75f, 1.0f, -0.5, -0.5, 0.25f, 0.5f, 0.5, -0.5} 0.75f, 0.5f} -0.5, 0.51 2 0.5, 0.5 -0.5, -0.5 0.5, -0.5 3 4
  • 41. centerJustifiedQuad[ ] = GLfloat quadTexture[ ] = { {-0.5, 0.5, 0.0f, 2.0f, 0.5, 0.5, 2.0f, 2.0f, -0.5, -0.5, 0.0f, 0.0f, 0.5, -0.5} 2.0f, 0.0f} -0.5, 0.51 2 0.5, 0.5 -0.5, -0.5 0.5, -0.5 3 4 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  • 42. Where the $#!% hits the fan ... glPushMatrix(); //transformations go here glBindTexture(GL_TEXTURE_2D, texID); glVertexPointer(3, GL_FLOAT, 0, quad); glTexCoordPointer(2, GL_FLOAT, 0, quadTexture); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glPopMatrix();
  • 43. Giminy Gee Willikers Batman! That’s a lot of stuff for one source file! Oh, he’s much more cunning than that... This is only the beginning of his Demo! genius plan makeSprite
  • 44. Ok, but what do we do when we have a lot of things? drawing is done in the order you call the draw methods depth buffer is rarely used because games almost always have partially transparent images Background Enemies Hero HUD
  • 45. Solution: Groups Background Enemies Background Enemies VS. Hero HUD Hero HUD (just sort within the layers)
  • 46. Discussion Scene/Asset managers Particle Engines Scene graphs and/or physics engine integration
  • 48. Q&A
  • 49. +1 M us Po hr we o o r !! m !! Ol ds t h ch d e M oo EN lt e AX o TH

Editor's Notes