Tuesday, July 13, 2010

OpenGL ES 2.0 Book Teaser

I've been making really good progress on the OpenGL ES 2.0 book for Prags, and I'm really happy with what I've done so far. The book isn't quite as hand-holding as Beginning iPhone 3 Development was, but it's probably more hand-holding than any graphics programming book I've ever read. If you've got prior experience with graphics programming, you may get frustrated with the pace of the book. I'm working on Chapter 8 now, and I haven't even gotten to lighting yet.

Those of you who have never worked with a programmable pipeline engine like OpenGL ES 2.0 or have tried and been frustrated by the books and resources available, will (I hope) appreciate the approach I'm taking. I'm trying to be very, very thorough. I'm trying not to leave any questions hanging in the air. I've found, over the years, graphics programming books to be frustrating in that they assume a certain level of prior knowledge that's not easy to obtain outside of college math classes. It's my goal to explain not only how to do things, but why, and give at least some high-level information about the underlying concepts and math. My goal is to make graphics programming approachable for people who don't necessarily have math knowledge beyond basic high school geometry and trig. I can't do that with everything. For example, with projection matrices, I simply didn't think it was worth trying to cover homogeneous coordinates, so I focused on how projection vectors worked and mostly skipped the why. But that's an exception. In most cases, I'm really focusing on why we do what we do.

Writing books like this is fun, to be honest. I'm learning OpenGL ES 2.0 at a much deeper level than I previously knew and I feel good about the progress of the book. From the discussions I've had, I think there's a lot of people out there who want to program in OpenGL ES 2.0 so they can do cool stuff on the iPhone and iPad, but who just don't really know where to start. It's like all the cool stuff is sitting on a shelf just out of reach. And that's frustrating.

I don't know yet when the book will be available. I'm hoping that it will get accepted into the beta books program when it's far enough along. If that happens, I'll make sure to post about it here, because then the book will be available for reading online before the official release.

Now, no part of the book is ready for public consumption yet, but I'm going to post some of my code from the book today. I know there's a shortage of good, clean, straightforward iOS OpenGL ES 2.0 code out there, so I though I'd post one of the projects from the chapter I'm working on now for anybody who wanted to try and figure out how it all fits together.

Although it's a a simple app, there's a fair amount going on. I take care of setting up a perspective projection and a model view matrix that both moves and rotates the object and also do texture mapping. There's a simple vertex shader and a fragment shader that take care of transforming the scene and doing the texture mapping. Now, in OpenGL ES 2.0, there are no built-in functions to handle any of these tasks, so it's all got to be done manually, primarily in the shaders. There are also some useful classes and functions you may be able to leverage in your own code. Much of what's in here is based on code I've posted in the past, but it's all been updated and tweaked for use in the OpenGL ES 2.0 programmable pipeline.

Screen shot 2010-07-13 at 11.24.55 PM.png
Yes, it's our old friend, the icosahedron, but all dressed up to look like a twenty-side die. Because, you know, what's more geeky than a twenty-sided die?

Now, this project hasn't been code reviewed. Heck, the chapter it's for hasn't even been written yet, so I'm sure there are mistakes and CBBs (could be betters). This is also not particularly efficient code. I'm putting off until later in the book a number of optimizations, including vectorizing the matrix and vector functions, interleaving per-vertex attributes, and using VBOs and VAOs. At this point, I'm much more focused on clarity and concepts than on performance, so just be aware of that before you decide to incorporate any of this code into a production project.

As always, there are no requirements placed on your use of this code. You don't have to give attribution, and you don't have to contribute back changes, though if you do fix or improve something, I'd be glad to hear about it.

You can find the Xcode project right here.

I've also made the original Blender and Pixelmator files I used to create the vertices and texture coordinates of the icosahedron as well as the texture. You can download those here.

I am sorry, but have to say that I won't be able to answer questions about the code. Between the book and client work right, most days I'm at my desk from 8:00 in the morning until 1:00 or 2:00 the next morning, seven days a week, so if you need explanations, you're going to have to wait for the book.


imabuddha said...

Thanks for posting this code. I'm eagerly waiting for the book!

K. A. Barber said...

Man, I was gonna go to bed... Another hour of code spelunking won't kill me for tomorrow morning will it?

Chris Miles said...

Thanks for the code! Runs fine on my iPhone 3GS (iOS 4) as well as my iPad (after a one-line change for compatibility with 3.2). I know almost no OpenGL and can't wait for the book.

Paul said...

I too am looking forward to the book, I'm hoping its going to cover things like degenerate triangles and how to combine multiple meshes into one single DrawArray?

At the WWDC during the Quest demo, they made the statement if you are drawing a scene like this with more than 10 draw statements you are doing it wrong!

Briz said...

Your OpenGL ES Tutorials are awesome. You are very though and well written which is hard to find even in a book. I look forward to the book. When do you imagine it will be out?

Scott Greiff said...

I don't think I'll ever need to code OpenGL ES, but I will buy this book! :)

JB said...

Thanks Jeff.. the direction you're taking talks directly to me. I've bought all the books and you arent kidding.. they expect you to already know what most of us bought the book to learn about in the first place.

chalk up 1 sale for the beta.!


Shane said...

Very cool. I've made it about halfway into the OpenGL ES 2.0 Programming Guide and it makes my head spin. Can't wait for your clear explanations of the concepts.

For anyone that is looking for a very clear and basic intro to vector based math check out "3D Math Primer for Graphics and Game Development" by Fletcher Dunn and Ian Parberry. It starts extremely basic and builds on previous concepts while teaching the why as well as the what of 3D math.

Jeff LaMarche said...


Multiple meshes in one draw statement isn't hard. If you're working with a 3D program (and for complex models, you usually will be), you simply export them together. You have to have some mechanism for knowing how to animate or move the different parts.

I took Jeff's statement at WWDC to mean "10 submits is where the performance starts to get worse" more than a "your design is flawed if you have more than 10 submits" but like you, I'd like some clarification on that. I may actually ask him. That team at Apple has some amazing chops, I generally trust what they say. Man, I'd love to spend a week just sitting in the room with them while they work. Not likely, though.


I really don't know. This is my first book with Prags, so I don't know the system well yet. I'm hoping to be done the manuscript by the end of next month. I'd love to be able to go on vacation with that monkey off my back, but I can't promise. I've got about 200 pages written so far, but now I'm starting to get into things that are harder to explain, so I may not be able to keep the pace I've been keeping.

I'm hoping for beta book status by September and dead-tree by end of year, but that may be overly optimistic.

Everyone else: thanks for the encouragement. I've wanted to write this book for a while. I ended up recruiting someone else to write a similar book for Apress so that I could focus on More iPhone 3 Development, but that fell through for reasons I don't know. I'm really happy that Prags has given me the opportunity to write basically the book I wish I would've existed when I was grappling with this stuff.

warmi said...

" If you're working with a 3D program (and for complex models, you usually will be), you simply export them together. You have to have some mechanism for knowing how to animate or move the different parts."

There are essentially two ways:

1. Export them as a single model for skeletal animation and use weights/bones to apply custom transformations.

2. Export them as multiple models and use Neon/VFP to transform separate models into a common vertex buffer.
This solution is better if you are already fillrate or otherwise limited on the GPU and have some CPU cycles to spare ( btw .. NEON is faster at this type of operations than the GPU ).
The downside of this approach is that you won't be able to fully utilize VBOs but , in my personal experience, it is a better choice as ( more often than not , especially with NEON,) your app will end up being GPU bound and on newer models with higher resolutions you will need every available GPU cycle just to handle increased fillrate demands.

warmi said...


Do you know if your book will be available in Apple e-bookstore ?

Jeff LaMarche said...


I haven't got a clue, to be honest.

You do know this book will be below your level of knowledge, right? :)

warmi said...

Nah ... there is always something to learn, even if only in terms of coding techniques.

Beside, I enjoying reading well written technical books.

Johan said...

Will definitly buy your book whenever it comes out...

Tried to get the project running on an iPad with 3.2.1 changing some project settings and such... no go sadly enough :) if fails on...

/3D Texture Mapping/Classes/Hello_GLAppDelegate.m:13:25 /3D Texture Mapping/Classes/Hello_GLAppDelegate.m:13:25: error: property 'contentScaleFactor' not found on object of type 'UIView *'

...which isnt supported in 3.2, I know :/) I will see if I can fix it in some way :)

I noticed that you use the ES2 includes everywhere except in the GLTexture.h file where you use ES1,
any specific reason?


Chris Miles said...

Johan, just comment out the "contentScaleFactor" line and it works fine on iPad. (Or better yet, add a compatibility check)

Johan said...

worked fine just removing that line and changing some settings in the project :)

Now to add some "touches" to the movement :) to learn how that works :)

Johan said...

BTW, still wonder why its ES1 in GLTexture but not anywhere else?

Jim said...

As you said it hasen't been reviewed but why are you keeping the interface builder files?

I would imagine it would be easier for new programmers to not have to deal with all the iphone "magic" which goes on here. Especially in a case where it isn't doing anything.

Somnath Banerjee said...

I cannot seem to get this built when I upgraded to XCode 3.2.4 and iOS 4.1.

I could get this compiled and run on older Xcode and using iOS 4.0 SDK running on the simulator.

Anyone facing similar issues?

BTW, this blog is just AWESOME! I cannot put this down ever since I found it. Great work Jeff!

Best Regards, Somnath

Jonathan Nobels said...

I couldn't build it in 4.1 either without modifications. I switched to GCC4.2 from LLVM 1.5 to get it to quit puking on the Apple headers then had to move all of (what appear to be) category defined iVars in the .m files into the main interface definition. You can leave the private methods.

Jeff - Defining additional iVars in a category is new to me... Is this a new language "feature" allowed by LLVM 1.5? When defining them specifically in the .m file, does the compiler add them statically at compile time? Is there any documentation regarding this somewhere? This is the first time I've come across this syntax.

SEO Services Consultants said...

Nice information, many thanks to the author. It is incomprehensible to me now, but in general, the usefulness and significance is overwhelming. Thanks again and good luck! Web Design Company