Getting Started

1. Create new project with window-based application.
2. Add OpenGL – OpenGLES.frameworks and QuartzCore.framework.
Modify OpenGLView.h

This imports the headers you need for OpenGL, and creates the instance variables that the methods you wrote earlier were using.
Set layer class to CAEAGLLayer

To set up a view to display OpenGL content, you need to set it’s default layer to a special kind of layer called a CAEAGLLayer.
The way you set the default layer is to simply overwrite the layerClass method
Set layer to opaque

By default, CALayers are set to non-opaque (i.e. transparent).
However, this is bad for performance reasons (especially with OpenGL), so it’s best to set this as opaque when possible.
Create OpenGL context

To do anything with OpenGL, you need to create an EAGLContext, and set the current context to the newly created context.

An EAGLContext manages all of the information iOS needs to draw with OpenGL.
It’s similar to how you need a Core Graphics context to do anything with Core Graphics.

When you create a context, you specify what version of the API you want to use.
Here, you specify that you want to use OpenGL ES 2.0. If it is not available (such as if the program was run on an iPhone 3G), the app would terminate.
Create a render buffer

The next step to use OpenGL is to create a render buffer, which is an OpenGL object that stores the rendered image to present to the screen.

Sometimes you’ll see a render buffer also referred to as a color buffer, because in essence it’s storing colors to display!

There are three steps to create a render buffer:
1.Call glGenRenderbuffers to create a new render buffer object. This returns a unique integer for the the render buffer (we store it here in _colorRenderBuffer). Sometimes you’ll see this unique integer referred to as an “OpenGL name.”

2.Call glBindRenderbuffer to tell OpenGL “whenever I refer to GL_RENDERBUFFER, I really mean _colorRenderBuffer.”

3.Finally, allocate some storage for the render buffer. The EAGLContext you created earlier has a method you can use for this called renderbufferStorage.
Create a frame buffer

A frame buffer is an OpenGL object that contains a render buffer, and some other buffers you’ll learn about later such as a depth buffer, stencil buffer, and accumulation buffer.

The first two steps for creating a frame buffer is very similar to creating a render buffer – it uses the glGen and glBind like you’ve seen before, just ending with “Framebuffer/s” instead of “Renderbuffer/s”.

The last function call (glFramebufferRenderbuffer) is new however. It lets you attach the render buffer you created earlier to the frame buffer’s GL_COLOR_ATTACHMENT0 slot.
Clear the screen

We’re trying to get something displaying on the screen as quickly as possible, so before dealing with vertexes, shaders, and the like, let’s just clear the entire screen to a particular color!

Let’s set it to the main color of this website, which is RGB 0, 104, 55. Notice you have to divide the color values by 255 (the max color value), because the color range for each component is from 0 to 1.

To accomplish this we have to take three steps here:
1.Call glClearColor to specify the RGB and alpha (transparency) values to use when clearing the screen.

2.Call glClear to actually perform the clearing. Remember that there can be different types of buffers, such as the render/color buffer we’re displaying, and others we’re not using yet such as depth or stencil buffers. Here we use the GL_COLOR_BUFFER_BIT to specify what exactly to clear – in this case, the current render/color buffer.

3.Call a method on the OpenGL context to present the render/color buffer to the UIView’s layer!
Wrapup code in OpenGLView.m

This is just some helper code to call all of the above methods, and clean up in dealloc.
Hook up OpenGLView to the App Delegate

This simply creates a new instance of the OpenGLView at startup, and attaches it to the window.
And that’s it! Compile and run your project, and you should see a green screen drawn by OpenGL ES 2.0!
Adding Vertex Shaders and Fragment Shaders

In OpenGL ES 2.0, to render any geometry to the scene, you have to create two tiny little programs called shaders.

Shaders are written in a C-like language called GLSL. Don’t worry too much about studying up on the reference at this point – you can get just by looking at the examples in this tutorial for now.

There are two types of shaders:
1.Vertex shaders are programs that get called once per vertex in your scene. So if you are rendering a simple scene with a single square, with one vertex at each corner, this would be called four times. Its job is to perform some calculations such as lighting, geometry transforms, etc., figure out the final position of the vertex, and also pass on some data to the fragment shader.

2.Fragment shaders are programs that get called once per pixel (sort of) in your scene. So if you’re rendering that same simple scene with a single square, it will be called once for each pixel that the square covers. Fragment shaders can also perform lighting calculations, etc, but their most important job is to set the final color for the pixel.

add two new empty files names SimpleVertex.glsl and SimpleFragment.glsl
1. The attribute keyword declares that this shader is going to be passed in an input variable called Position. Later on, you’ll write some code to pass some data into this input variable. It will be used to indicate the position of the Vertex. Note that the type of the variable is a vec4, which means a vector with 4 components.

2. This declares a second input variable, for the color of the vertex.

3. This declares another variable, but it doesn’t have the attribute keyword, so is an output variable that will be passed to the fragment shader. It also has the varying keyword, which is a fancy way of saying “I’m going to tell you the value for a particular vertex, but when you need to figure out the value for a given pixel, figure it out by smoothing out the values between nearby vertexes.”

So basically, you can specify a different color for each vertex, and it will make all the values in-between a neat gradient! You’ll see an example of that for yourself soon.

4. Every shader begins with a main – just like C!

5. Sets the destination color for this vertex equal to the source color, and lets OpenGL interpolate the values as explained above.

6. There’s a built in output variable you have to set in the vertex shader called gl_Position equal to the final position of the vertex. Here was just set it to the original position without changing it at all
1. This is the input variable from the vertex shader. It’s the exact same definition as the vetex shader had, except it has an additional keyword: lowp. Turns out when you specify variables in a fragment shader, you need to give it a precision. A good rule of thumb is try to use the lowest precision you can get away with, for a performance bonus. We set it to the lowest precision here, but there’s also medp and highp if you need it.

2. Just like in a vertex shader, a fragment shader also begins with main.

3. Just like you need to set gl_Position in the vertex shader, you have to set gl_FragColor in the fragment shader. This simply sets it to the destination color passed in (interpolated by OpenGL).
Compiling Vertex and Fragment Shaders

We’ve added the two shaders to our Xcode project as glsl files, but guess what – Xcode doesn’t do anything with them except copy them into our application bundle.

It’s the job our our app to compile and run these shaders – at runtime!

You might be surprised by this (it’s kinda weird to have an app compiling code on the fly!), but it’s set up this way so that the shader code isn’t dependent on any particular graphics chip, etc.

So let’s write a method we can use to compile these shaders.
1. Gets an NSString with the contents of the file. This is regular old UIKit programming, many of you should be used to this kind of stuff already.

2. Calls glCreateShader to create a OpenGL object to represent the shader. When you call this function you need to pass in a shaderType to indicate whether it’s a fragment or vertex shader. We take ethis as a parameter to this method.

3. Calls glShaderSource to give OpenGL the source code for this shader. We do some conversion here to convert the source code from an NSString to a C-string.

4. Finally, calls glCompileShader to compile the shader at runtime!

5. This can fail – and it will in practice if your GLSL code has errors in it. When it does fail, it’s useful to get some output messages in terms of what went wrong. This code uses glGetShaderiv and glGetShaderInfoLog to output any error messages to the screen (and quit so you can fix the bug!)
to compile the vertex and fragmetn shaders, there’s a few more steps – linking them together, telling OpenGL to actually use the program, and getting some pointers to the attribute slots where you’ll be passing in the input values to the shaders.
Add a new method to do this right below compileShader:

Here’s how each section works:
1. Uses the method you just wrote to compile the vertex and fragment shaders.

2. Calls glCreateProgram, glAttachShader, and glLinkProgram to link the vertex and fragment shaders into a complete program.

3. Calls glGetProgramiv and glGetProgramInfoLog to check and see if there were any link errors, and display the output and quit if so.

4. Calls glUseProgram to tell OpenGL to actually use this program when given vertex info.

5. Finally, calls glGetAttribLocation to get a pointer to the input values for the vertex shader, so we can set them in code. Also calls glEnableVertexAttribArray to enable use of these arrays (they are disabled by default).

Two last steps. Add the following method call to initWithFrame right before calling render
And declare the instance variables for _colorSlot and _positionSlot inside the @interface in OpenGLView.h as follows
Creating Vertex Data for a Simple Square

When you render geometry with OpenGL, keep in mind that it can’t render squares – it can only render triangles. However we can create a square with two triangles as you can see in the picture above: one triangle with vertices (0, 1, 2), and one triangle with vertices (2, 3, 0).

One of the nice things about OpenGL ES 2.0 is you can keep your vertex data organized in whatever manner you like. Open up OpenGLView.m and create a plain old C-structure and a few arrays to keep track of our square information

So basically we create:
a structure to keep track of all our per-vertex information (currently just color and position)
an array with all the info for each vertex
an array that gives a list of triangles to create, by specifying the 3 vertices that make up each triangle
Creating Vertex Buffer Objects

The best way to send data to OpenGL is through something called Vertex Buffer Objects.

Basically these are OpenGL objects that store buffers of vertex data for you. You use a few function calls to send your data over to OpenGL-land.

There are two types of vertex buffer objects – one to keep track of the per-vertex data (like we have in the Vertices array), and one to keep track of the indices that make up triangles (like we have in the Indices array).

You can see that it’s pretty simple. It uses a similar pattern that you’ve seen before – calls glGenBuffers to create a new Vertex Buffer object, glBindBuffer to tell OpenGL “hey when I say GL_ARRAY_BUFFER, I really mean vertexBuffer”, and glBufferData to send the data over to OpenGL-land.

And add this to initWithFrame right before calling render:
Updated Render Code

We have all of the pieces in place, finally we can update the render method to draw our new vertex data to the screen, using our new shaders!

This works as follows:
1. Calls glViewport to set the portion of the UIView to use for rendering. This sets it to the entire window, but if you wanted a smallar part you could change these values.

2. Calls glVertexAttribPointer to feed the correct values to the two input variables for the vertex shader – the Position and SourceColor attributes.

This is a particularly important function so let’s go over how it works carefully:

The first parameter specifies the attribute name to set. We got these earlier when we called glGetAttribLocation.

The second parameter specifies how many values are present for each vertex. If you look back up at the Vertex struct, you’ll see that for the position there are three floats (x,y,z) and for the color there are four floats (r,g,b,a).

The third parameter specifies the type of each value – which is float for both Position and Color.

The fourth parameter is always set to false.

The fifth parameter is the size of the stride, which is a fancy way of saying “the size of the data structure containing the per-vertex data”. So we can simply pass in sizeof(Vertex) here to get the compiler to compute it for us.

The final parameter is the offset within the structure to find this data. The position data is at the beginning of the structure so we can pass 0 here, the color data is after the Position data (which was 3 floats, so we pass 3 * sizeof(float)).

Ok back to the final part of the code listing!
3. Calls glDrawElements to make the magic happen! This actually ends up calling your vertex shader for every vertex you pass in, and then the fragment shader on each pixel to display on the screen.

This is also an important function so let’s discuss each parameter here as well:

The first parameter specifies the manner of drawing the vertices. There are different options you may come across in other tutorials like GL_LINE_STRIP or GL_TRIANGLE_FAN, but GL_TRIANGLES is the most generically useful (especially when combined with VBOs) so it’s what we cover here.

The second parameter is the count of vertices to render. We use a C trick to compute the number of elements in an array here by dividing the sizeof(Indices) (which gives us the size of the array in bytes) by sizeof(Indices[0]) (which gives us the size of the first element in the arary).

The third parameter is the data type of each individual index in the Indices array. We’re using an unsigned byte for that so we specify that here.

From the documentation, it appears that the final parameter should be a pointer to the indices. But since we’re using VBOs it’s a special case – it will use the indices array we already passed to OpenGL-land in the GL_ELEMENT_ARRAY_BUFFER.
Adding a Projection

You may be wondering why this rectangle happens to fit perfectly on the screen. Well by default, OpenGL has the “camera” at (0,0,0), looking down the z-axis. The bottom left of the screen is mapped to (-1,-1), and the upper right of the screen is mapped to (1,1), so it “stretches” our square to fit the entire screen.
Obviously, in a real app you’ll want to have more control over how the “camera” behaves. So let’s talk about how you can do that with a projection transform

To make objects appear 3D on a 2D screen, we need to apply a projection transform on the objects. Here’s a diagram that shows how this works:

Basically we have a “near” plane and a “far plane”, and the objects we want to display are in-between. The closer an object is to the “near” plane we scale it so it looks smaller, and the closer and object is to the “far” plane we scale it so it appears bigger. This mimics the way a human eye works.

Here we add a new input variable called Projection. Notice that instead of marking it as an attribute, we mark it as a uniform. This means that we just pass in a constant value for all vertices, rather than a per-vertex value.

Also note that the Projection is marked as a mat4 type. Mat4 stands for a 4×4 matrix. Matrix math is a big subject that we won’t really cover here, but for now just think of them as things you can use to scale, rotate, or translate vertices. We’ll pass in a matrix that moves our vertices around according to the Projection diagram above.

Next, we set the final position of the vertex to be the Projection multiplied by the Position. The way you apply a matrix transform on something is to multiply like we did here! Order does matter by the way.
Now you need to pass in the Projection matrix to your vertex shader. However, this involves some complicated linear algebra and sadly I have forgotten too much of that since my college days :[ But luckly you don’t need to understand it to use it, since this is well known stuff that many smart people have already solved!

Smart people like Bill Hollings, the author of Cocos3D. He’s written a full-featured 3D graphics framework that integrates nicely with Cocos2D (and maybe I’ll write a tutorial about it sometime!) But anyway, Cocos3D contains a nice Objective-C vector and matrix library that we can pull into this project quite easily.

drag the Cocos3D Math Library files into project.

add a new instance variable to OpenGLView.h inside the @interface:

Here we import the header for the math library, and call glGetUniformLocation to get the handle we need to set the Projection input variable in the vertex shader.

Then, we use the math library to create a projection matrix. It comes with a nice and easy to use function that lets you specify the coordinates to use for the left/right and top/bottom for the planes, and the near and far z-coordinates.

The way you pass that data to the vertex shader is through glUniformMatrix4fv, and the CC3GLMatrix class has a handy glMatrix method that converts them matrix into the array format OpenGL uses.

The last step is to tweak our vertices a bit so they fit within the near/far planes. This just sets the z-coordinate for each vertex to -7.