OpenGL FAQ

Sage
Posts: 1,234
Joined: 2002.10
Post: #1
Over the last several years, iDevGames has seen many great questions and discussions about all manner of Mac-related game development.

With the advent of the iPhone, there has recently been a increase in new developers posting questions here. And I think a lot of the same basic questions are asked over and over. In particular, questions about a subject near and dear to my heart-- OpenGL.

In my experience, at least 90% of these questions can be completely answered to anyone's satisfaction by simply reading the OpenGL documentation. But the official documentation is written in quite verbose and technical language, and may not be easy for new developers to pick up and digest, so it seems that many people don't bother reading it.

To point out some other resources, there is an official OpenGL FAQ as well as a wiki and forum. Apple also maintains an OpenGL page with various articles, tools, and sample code demonstrating best practices on the Mac. Apple also has a mac-opengl mailing list with a searchable archive of thousands of questions and answers. And there's a new Apple developer forum for iPhone discussion. Many people learn best by example, and in addition to the official collection of OpenGL examples several others are available online, such as NeHe, CodeSampler, and of course Nvidia's SDK and AMD's SDK. Many books have been written about OpenGL if that's easier for you to learn with.

After reading and playing with all of this, you'll understand the fundamental operation of OpenGL. That leaves us with the other 10% of the questions, which tend to be "what's the best way to do X?" or "I'm trying to do X and it works on GPU Y but not GPU Z, why?". Usually, these questions can be answered by experience, or in many cases by simply trying several implementations and comparing them. And sometimes, we really need nice long discussions. Smile

The "FAQ" link on this forum is broken, so in this thread, I'd like to ask iDevGamers what you want in a FAQ. What's important to you?

From my perspective, there are a couple of fundamental topics that should be clearly documented. Of course these are already covered in other FAQs, but this is how I'd order a list tuned to new developers on iDevGames:

1) How to program. This is outside of the realm of OpenGL, but it's absolutely crucial that you understand the basic concepts of C and how to write and debug a program before you try to make a game using OpenGL. So, see a "general programming" FAQ before going any further.

2) What is OpenGL. Strictly speaking, it's nothing more than a specification. In practice, it's a state-machine based 2D and 3D graphics API abstracting away the hardware details so that you don't have to write microcode specific to every GPU you want your game to run on. This leads to a discussion of how hardware-specific features are exposed via extensions, which is a whole topic by itself.

3) What can I do with OpenGL? It's a fairly low-level API, which (to grossly simplify things) lets you draw a bunch of texture-mapped triangles. It's not a scene graph or a game engine-- you build those things on top of OpenGL. For a new platform like the iPhone, I think it's best to understand what the hardware and API capabilities are, and design your game around that-- not the other way around.

4) What's the deal with OpenGL ES? Embedded devices like the iPhone support a small subset of the full OpenGL API; many older and "convenience" functions have been removed. The two API are generally compatible, so you can write an application for both the Mac and the iPhone if you're careful about the functions you use. This leads to a discussion of the history of the GL API and the widely differing capabilities of the various GPUs out there.

A series of "how do I?" topics, like:
5) How do I set up rendering (choosing a device, creating a context, creating a drawable.)
6) How do I draw something (vertex attributes and transformation.)
7) How do I use textures (texture objects, filtering, TexEnv.)

8) Everything else. Input, Audio, Video, Timing, Physics, File I/O, etc are not part of OpenGL.

So, is this useful to build up with more detail? After reading everything I linked above, what else do you still want to know?
Quote this message in a reply
Sage
Posts: 1,234
Joined: 2002.10
Post: #2
How to Debug

Here, I'll discuss a few fundamental techniques for debugging anything in OpenGL. See also: Getting Started, Common Mistakes.
  • Check for errors. If you call any OpenGL function with invalid arguments (or try to do something impossible, like draw with an invalid framebuffer object), it will set a global error and do nothing. You'll see broken or unexpected rendering as a result.

    A good general practice while you're debugging is to call glGetError in the main loop of your program. Right at the end where you swap the framebuffer is a good place. If glGetError returns non-zero, then you've used the API incorrectly somewhere. The global error is sticky, so it's not necessarily caused by the most recent GL call, it could have been from many calls ago. You can sprinkle glGetError checks around your functions to narrow it down to the exact call, or you can use OpenGL Profiler's "Break on Error" checkbox to find the exact call immediately.

    Note that for performance reasons, you should only call glGetError in your Debug build. After your app is tested and debugged on all hardware configurations you need to support, turn the error checking off in your Release build.

  • Introspect the current state. An OpenGL context is a large collection of state, and bugs can often be caused by setting the state one way, and then forgetting to reset it later. All of the state in desktop OpenGL (and most of the state in OpenGL ES) can be be queried at any time, so you can verify it is as you expect. Again, this should only be done in your Debug build, not in your Release build.

    As a simple example, let's say you're trying to draw a 3D scene and the objects overlap incorrectly, or when you rotate an object the back side of it shows up instead of the front side. This sounds like a problem with depth testing, so double check the state that could interact. For example, glIsEnabled(GL_DEPTH_TEST), glGetInteger(GL_DEPTH_FUNC, ...), glGetInteger(GL_DEPTH_BITS, ...) will show the most likely problems. A complete list of all the context state you can query is given in the state table near the end of the specification for the relevant GL version.

    Another example of a common state problem is drawing while vertex array state has been left set up incorrectly. You'll usually crash if you do this, when OpenGL tries to dereference vertex data from the invalid pointers you gave it, but sometimes you'll see corrupt geometry or other strange problems. The same technique applies-- query all of the vertex array state (pointers, stride, type, client enables, buffer object bindings, etc) to make sure it's what you expect. You can make a "ValidateState" debug function, and use it before every draw.

    OpenGL Profiler can help you debug state problems by showing all of the context state at any breakpoint, including convenient checkboxes to highlight the state that has changed from the default, or from the previous time you hit a breakpoint.

  • Break your problem down step by step. Typical scenes have many objects, and perhaps many passes to draw everything. Each pass usually needs its own state setup. Programmatically, you can simply comment out objects or passes in your code to verify which ones work and where the problem starts. After locating the first incorrect rendering, inspect the state and how your app created the input data to OpenGL (matrices, textures, vertex data, etc.)

    You can also use OpenGL Profiler to run your application and watch your scene being drawn one step at a time. In Profiler, set a breakpoint after every GL call that you use to draw (glEnd, glDrawArrays, glDrawElements, etc). Then view the back buffer (and optionally depth, stencil, alpha buffers.) When you run, Profiler will break after each draw, and you can visualize the scene being built up. At each step, you can inspect all of the state to understand the inputs GL used to process the drawing.

Quote this message in a reply
Member
Posts: 31
Joined: 2009.01
Post: #3
I think it's very useful. I came from a direct x background so although the concepts are similar there are some differences. Although I had to read info on several different websites. This info could be useful to people i.e. Left Handed Coordinate system vs Right Handed, and the different views open gl maintains.

For myself a big interest would be a section on optimizations. I admit I haven't profiled much OpenGL code and at this time am unsure what operations are costly.
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #4
Thank you arekkusu! This is going to be a very important thread to build out as you wish, so I stickied it.
Quote this message in a reply
Apprentice
Posts: 12
Joined: 2009.01
Post: #5
I for one would love to see this thread expanded with what you have listed here.
Quote this message in a reply
Member
Posts: 312
Joined: 2006.10
Post: #6
Other things that might be worth mentioning are specific ways to speed up rendering. For example, what are the pros and cons of: instancing, storing a lot of (unrelated) vertex data in one VBO opposed to several separate ones, indices vs normal vertex arrays, interleaved data vs a vertex array for each, ect...

And since the trend in graphics programming is all shader-based, it'd be nice to have FAQ of what should be avoided and what shouldn't be if you're preparing to go that direction, and general "sub-FAQ" for shader programming in general.

Overall though, nice!
Quote this message in a reply
Post Reply