Monday, May 4, 2009

OpenGL ES From the Ground Up, Part 1 Addendum: Alphabet Soup

One problem with blog postings is that they are self-edited. For my postings here, I have no external technical review and no copy editing done. Mostly, it's not too much of a problem, as smart people read this blog and quickly point out my errors, and people seem to be pretty forgiving of the occasional grammatical or spelling gaffe.

But, sometimes, the result of this being a one-man production is that I miss something that I really, really should have included. While re-reading part 4, I realized that I used both glLightfv() and glLightf() and it occurred to me that I never explained the naming format for OpenGL function calls. Back in part 1, I went through all the trouble of explaining the different OpenGL datatypes, but I didn't explain how they related to the alphabet soup at the end of the function call.

So, let me rectify this for those of you that haven't figured it out already.

OpenGL calls that don't take any parameters don't have alphabet soup at the end.There is only one version of those methods. Here's an example:

    GL_ENUM error = glGetError();

The same is basically true for methods that take only a specific type of parameter, such as GL_ENUM:


However, the vast majority of OpenGL function calls can be made using more than one dataype. This is much more pronounced in regular OpenGL, where most function calls have at least a half-dozen different variants, allowing you to pass GLshort, GLbyte, GLint, GLfloat, GLDouble, or GLfixed by value or by reference. In OpenGL ES, there's a much smaller subset of function calls and datatypes, so it's not quite as daunting or confusing, however OpenGL ES still follows the same naming convention, so it's a good idea to understand what that alphabet soup means.

The first and sometimes the second letter after the name of the function specify the datatype that this method takes. Here is a chart that explains what each suffix refers to:
  • b    GLbyte
  • s    GLshort
  • i    GLint
  • f    GLfloat
  • ub   GLubyte
  • us   GLushort
  • ui   GLuint
So, glFoof() would expect a glFloat to be passed in, while glFoos() would expect a GLshort.
Note: In regular OpenGL, there might also be a number as part of the suffix. This number would represent the number of that datatype that is needed. So, for example, the function glVertex3f() takes three GLfloats. Since this naming convention is mostly used in direct mode, which OpenGL ES doesn't have, you won't see this naming convention as often in OpenGL ES, however there are a few functions that follow this naming convention like glColor4f(). OpenGL ES doesn't support, for example, glColor3f(), but keeps the number as part of the prefix to maximize compatibility between the two APIs

As you saw back in Part 4, sometimes functions serve a more generic purpose, such as glLightf(). You call this method to set many different attributes of a given light. You use this call to set, for example, the spot cutoff as well as the light's position in 3D space. Spot cutoff requires a single value, but the light's position requires three.

For these functions, there is an additional variant marked by a v at the end of the method name, after the datatype letters. If you need to pass a regular datatype to OpenGL, you don't use this suffix and just pass in the datatype you need by value. But, if you need to provide more than a single OpenGL native datatype (in other words, that list from Part 1), then you have to put the values into an array and pass a pointer to the beginning of that array. When you pass values into OpenGL by reference like this, then you use the function call with the v suffix.

So, back in Part 4, when we told OpenGL the spot cuttoff value ,we used the regular non-v version, like this:

    glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);

but, when we passed in the light's position, which takes three GLfloats, we used the v variant and passed in an array, which is exactly the same thing as passing a pointer to the first value of the array:

    const GLfloat light0Position[] = {0.0, 10.0, 10.0, 0.0}; 
glLightfv(GL_LIGHT0, GL_POSITION, light0Position);

I hope this helps anyone who was confused by the function names. At some point, I'll try and integrate this information into part 1, but I since it was kind of an obvious oversight on my part, I wanted to post it.


ahitech said...


I just want to thank you for the crash course in OpenGL. Although I'm not an Apple iPhone user/programmer (yet), the crash course was extremely helpful. Thank you very much!

I will be glad to read about backface culling, and, especially, on ways to make a polygon be counted as "forward" no matter what's the order of its vertices, clockwise or counterclockwise. But, anyway, your development notes are very interesting and useful. Keep up the good work! And thanks again!

The Bored Koi said...

A hearty second to ahitech's comment -- so far, you're my sole beacon in the OpenGL ES darkness. I am fortunate enough to have a strong math, geometry, trig, and physics background, but the one thing I sorely lack is OpenGL syntax and procedure. I'm borrowing so heavily from your experience and gracious posts that I'm compelled to buy that book of yours (albeit a broader view of iPhone development than just OpenGL).

Now..back to tinkering with my Particles mod... :)

VesperDEM said...

When running the latest version of your app, I get an error message "500 error".

I found that if I comment out the line:
glLightf(GL_LIGHT0, GL_SHININESS, 0.4f);

the error goes away. I did some research and found that glLight doesn't use GL_SHININESS. That value is associated with materials.

So, my question is: Is this line an error. Should it be in a future 3D article that touches on materials?

Thanks for what you have so far. This is the best walkthrough of OpenGLES I have found on the web so far. I find all the descriptions and samples very easy to follow. I'm really looking forward to the rest of this.

Thanks so much for your hard work on it.

Jeff LaMarche said...


Sorry about that - I screwed up. I fixed the blog post a while ago, but probably should have made an announcement so people who had read it before the fix could go re-read the part I changed.

What happened was: I originally had materials and lights as part of a single blog posting, but it became too long, so I decided to split it into two, doing lights first, and then materials in a separate posting. Unfortunately, I missed that attribute when I split the article - shininess is actually an attribute of materials not of lights and shouldn't have been in this posting at all.

Sorry for the inconvenience.

spamisfreespeech said...

This blog is brilliant.

sam said...

extremely helpful for one from all i have read till now..!1

Edwin said...

scrub m65 kamagra attorney lawyer body scrub field jacket lovegra marijuana attorney injury lawyer

h4ns said...

What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say. Im sure youll reach so many people with what youve got to say.

Arsenal vs Huddersfield Town live streaming
Arsenal vs Huddersfield Town live streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Notts County vs Manchester City Live Streaming
Notts County vs Manchester City Live Streaming
Bologna vs AS Roma Live Streaming
Bologna vs AS Roma Live Streaming
Juventus vs Udinese Live Streaming
Juventus vs Udinese Live Streaming
Napoli vs Sampdoria Live Streaming
Napoli vs Sampdoria Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
AS Monaco vs Marseille Live Streaming
AS Monaco vs Marseille Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Technology News | News Today | Live Streaming TV Channels