Thursday, October 28, 2010

OpenGL ES 2.0 for iOS, Chapter 1 - Introduction

It is not an exaggeration to say that the iPhone SDK and the App Store have forever changed the way that mobile applications are developed and sold. By building the iPhone SDK on the foundation laid by NeXT with NextSTEP, which later became Apple's Cocoa framework for developing desktop applications, Apple was able to provide third-party developers of their new mobile platform with tools and some APIs that already had the benefit of over 20 years of use, testing, and documentation. Although iOS, of course, contains a great amount of new code designed specifically to handle the needs of a touch-based, mobile computing platform, many of the classes that implement fundamental behavior in the iOS SDK have been in regular use since the late 1980s; that code is extraordinarily robust and thoroughly documented.

But a mobile platform is different from a desktop or laptop computer in many ways, and not all of the technology that makes up the iPhone is as well-documented or as well-understood as the foundation classes inherited from NextSTEP. One such technology is OpenGL ES, a graphics library designed for use on smaller devices, with limited processing power and memory (the ES stands for embedded systems). Although the iPhone, iPod touch, and iPad are, in many ways, engineering marvels, they are still considerably underpowered compared to today's laptop and desktop computers. They have less RAM, slower processors with fewer processing cores, and a less powerful GPU than even inexpensive general-purpose computers. iOS applications, such as games, that want to fully leverage the graphics capabilities of the iPhone generally have to use OpenGL ES to get the best possible performance out of the hardware.

Yet if you go looking for specific beginner-level information about how to use OpenGL ES on the iPhone, it can be hard to find. Although there are a great many books, tutorials, and articles on OpenGL, of which OpenGL ES is a subset, nearly every one starts out teaching something called direct mode, which doesn't exist in OpenGL ES (or the most recent OpenGL specification, for that matter). Direct mode was one of the earliest ways to interact with OpenGL, but it's not used much in practice because it's slow. In direct mode, you perform a separate C function call for every single piece of data or instruction you need to pass in to OpenGL. To draw a triangle, for example, you have to make four function calls (in addition to any setup code), one call to define the location of each of the three points that make up the triangle, then another function call to actually draw the triangle. For complex objects, direct mode code quickly becomes tedious and inefficient.

Direct mode was kept in workstation OpenGL for many years past when it was a viable option not just for backward compatibility, but also because it was a tremendous tool for learning. By having to break the drawing process down into all these individual function calls, the programmer who is new to graphics programming and the mathematics of drawing is able to conceptualize what is going on more easily. After spending a while with direct mode, new developers can begin to understand how OpenGL works; by the time they are introduced to more efficient ways of submitting data to OpenGL, they have a good grounding and are ready for the conceptually harder techniques.

Without direct mode, programmers new to OpenGL ES are forced to begin using these harder techniques immediately. There's no gradual entry into the OpenGL ES pool: you have to just jump right into the deep end. And if you don't already know how to swim, jumping in to the deep end can be pretty intimidating.

To make matters worse, to fully leverage the power of today's iOS devices, you have to use OpenGL ES 2.0, and OpenGL ES 2.0 has an even steeper learning curve than earlier versions. OpenGL ES 2.0 dropped support for something called fixed pipeline rendering which provided a number of stock function calls for handling common tasks such as setting up lights, moving and rotating objects, and defining the part of the world to be rendered. Under the fixed pipeline, for example, if you wanted to rotate an object, you would simply call the built-in function glRotatef() before drawing, which would tell OpenGL ES how far and on what axis to rotate the object before drawing it. With OpenGL ES's focus on performance, once the programmable pipeline was introduced in OpenGL ES 2.0, support for the fixed pipeline was completely dropped, meaning all those convenient methods for setting up and moving objects around your scene are gone. OpenGL ES 1.1 applications will not even compile under OpenGL ES 2.0. Not only is OpenGL ES 2.0 the deep end of the pool, it's the deep end of a very deep, very wide, and very cold pool.
Don't worry if you don't understand what the pipeline is, or what the difference between a fixed and a programmable pipeline is. That will be explained in future chapters.
Think of this book as a life vest for OpenGL ES 2.0. You're still going to have to jump into the deep end right from the start, but I should be able to keep your head above water most of the time.

What You Need to Know

To use this book, you don't need to already know anything about OpenGL, OpenGL ES, or even about graphics programming in general. You will, however, need to understand the basics of programming and, specifically, programming in Objective-C for iOS devices. This means you'll need to be comfortable with both the Objective-C language, as well as straight C. You should have some familiarity with the various frameworks that make up the iPhone SDK and be familiar with basic programming concepts, including memory management. Although I'll be going slowly as I introduce you to 3D concepts, I won't be explaining basic programming concepts such as the difference between allocating memory on the stack and on the heap. If you're rusty or unsure, it's a good idea to brush up on programming basics before proceeding. You also should be familiar with the basics of working in Xcode.

One of the difficulties in writing a book on introductory level OpenGL ES is choosing what to cover. The topic is expansive. The official OpenGL books alone amount to several thousand pages of material, and those generally assume a certain level of existing math and graphics programming knowledge. There's simply no way to cover the topic exhaustively in a single book. One of my personal frustrations when originally learning graphics programming was the assumption most books seemed to have that you already had a really strong math foundation and that information was still fresh in your mind. I'm not going to make that assumption. I don't expect you to have received a doctoral degree in mathematics before reading this book and writing your first OpenGL ES application. However, because graphics programming is so heavily dependent on math, you do need a basic working knowledge of high-school level math, especially basic geometry and trigonometry.

What You Need to Have

In order to get the most out of this book, you need access to an Intel Mac and be a member of Apple's iPhone Developer Program. Make sure to download the latest version of the iPhone SDK before beginning. Although you'll be able to run much of the code in this book on the iPhone Simulator, to get the most out of it, you'll need to be able to run applications on your iPhone, iPad, or iPod touch, so one of the paid iPhone SDK memberships, which give you the ability to run applications on a physical device, is highly recommended. OpenGL ES programming can be very processor-intensive, and the iPhone Simulator running on your Mac won't give you a good indication of how well your programs will perform on an actual iOS device, because all iOS devices have a slower processor and less RAM than even the lowest-end Macs.

A Note About Language Choice

Before we get started, I want to take a quick second to talk about my choice of programming languages. In this book, I'm going to be using Objective-C. Objective-C is a superset of C, and in many places, I will leverage that fact and use good old-fashioned C functions, structs, and datatypes instead of using higher-level Objective-C objects.

What I won't be doing is using C++.

I know that many OpenGL ES books and other resources use C++, and even operate under the assumption that any other language choice would be foolish. For iOS programming, that's simply an incorrect assumption.

Objective-C is the lingua franca of iPhone development. The entire Cocoa Touch framework is written in Objective-C, as are the foundation objects you'll need to pass to most of the iOS APIs. It is true that Objective-C and C++ code can work together using something called Objective-C++, and Objective-C++ is an amazing piece of engineering. But it has also been described as an “unholy marriage” and a “marriage of convenience” by engineers on Apple's compiler team. It's a great resource if you have large existing libraries of C++ code or if you're porting something that was written in C++ from another platform. But if you're starting from scratch on the iPhone, Objective-C really is the way to go.

The reason that Objective-C++ is an “unholy marriage” is because the two languages evolved from very different sources and use very different object models. C++ uses an object model derived from a programming language called Simula. Simula-derived languages like C++ are strongly typed and use static dispatching, which means that determining how a member function gets called happens at compile time. Basically, C++ does a lot of checks and rules enforcement at compile time, restricting what you can do in order to prevent you from shooting yourself in the foot. Objective-C, on the other hand, uses an object model based on Smalltalk, which is loosely typed and dynamically dispatched. Objective-C is much more permissive, and defers many tasks to runtime that C++ handles at compile time. There are arguments for both approaches---as well as times when one is clearly a better choice---but any way you look at it, they are fundamentally different languages, far more than just the syntactical differences. As a result, you tend to use drastically different patterns when using the two languages.

The reasons most often given for using C++ are performance and portability. When it comes to performance, it is true that C++ has slightly less overhead when it comes to object creation and destruction compared to Objective-C's allocation and deallocation, as well as a little less overhead when it comes to calling member functions when compared with Objective-C's dynamic dispatch mechanism. However, in both cases, the overhead is more than using the low-level C functionality that both languages rest on top of. For example, free() malloc() is less costly than either C++'s new or Objective-C's alloc and init. When performance is potentially an issue (and performance is often a potential issue when doing graphics programming on an embedded device), I'll avoid the overhead of the object model completely and use straight C. Since both Objective-C and C++ are supersets of C, C code can be used in both C++ and Objective-C without any bridging or unholiness at all. As for portability, it is true that C++ is still a more commonly used language than Objective-C, though how much of an issue that is in the mobile space, where Java is the next most commonly used language after Objective-C, is debatable.

Let's Go!

We've got a lot to do, and a lot of it is really cool. I'll try and get Chapter 2 posted quickly.


StarkHalo said...

Thanks Jeff!

gms said...

Thank-you. This is great stuff.

testsss said...

thanks. Awesome timing, just when I decide to dive deep into openGL ES :D

Jens Ayton said...

Erratum: drawing a triangle in immediate mode requires five function calls (glBegin, 3 × glVertex, glEnd).

Zwilnik said...

For example, free() malloc() is less costly than either C++'s new or Objective-C's alloc and init

You can't really say that definitively. C++ new is an overloadable operator. new for a given object can easily be faster than malloc: that's part of the point. alloc in ObjC is just a class method, and could theoretically also have an implementation specific to the class and faster than malloc (would have to be really superfast to overcome the method dispatch overhead though)..

Séries said...

Hey Jeff.

I was learned so much with you months ago.

Few months ago I was completely new to OpenGL 2.0.
Is really hard to find today good instructions to OpenGL 2.0.

The Khronos docs is really dense and a lot abstract. For newbies, is very confused. After learn some good concepts about OpenGL, the read of OpenGL ES 2.0 specs come more clearly.

Today I'm going from Intermediate to High programer level in OpenGL ES 2.0. And if you let me, I want to give you an advice.

I know that you are writing for who is newbie in OpenGL ES. But if I think like a beginner again, and read this chapter of your book, realy, I would have stopped and searched another book!

The art of write is very very laborious. Writers says that writing is 1% inspiration and 99% perspiration. Your chapter seems good, but I think that you went beyond the line of the details.
Fewer details like Khronos specs is bad, but so much details like you, is bad too.

Think like a newbie, I would have said on the middle of the chapter: "Oh right, right! I get it!! Go further!!! Go!"

Is this man,
Congratulations for the rest.

saintpumpkin said...

You rock man :) thank's for this stuff

xiamenb2c02 said...

EFX bracelet is energetic technology designed to instantly increse power.
EFX braceletis an embedded wearable holographic technology

designed to.Shop for high quality wholesale efx bracelet products on DHgate and get worldwide delivery.
silly bandz are a brand of silicone rubber bands formed into shapes including animals, These colorful
silly bandzare made of silicone and die molded in many different

fun shapes. They come in all different shapes, like foods, letters and animalsand and so on.welcome to enjoy colorful silly bandz for free shipping.
Hot sale products,Power shipping.

Cheapsocceruniforms said...

There are many brand from France, also including herve leger, and most of womens stars love wearing herve leger dress when they join in some important party. Now polo ralph lauren is very popular with youthful people, everyone want to get ralph lauren polo shirts, there are lots of online shop which are ralph lauren polo outlet, true religion jeans outlet, it will be convenient for us.