2D game techniques in OpenGL

I am writing a 2D platform game in Carbon (on OS X 10.3.0, so Tiger-specific stuff doesn't apply to me), and recently I have decided to convert all my slow QuickDraw code to OpenGL. So, I'd like to clarify some issues regarding the transition to OpenGL.

- First, I've noticed that there are a lot of recommendations to use texture mapping to get stuff on-screen. But I was wondering: what is the difference between texture mapping and glDrawPixels() in 2D games? Performance? (I'd like to avoid texture mapping because of the rule that the image dimensions must be a power of 2.)

- Second, is it possible to play QuickTime movies in an AGL window and full screen context via aglGetDrawable()? Or a GLUT window?

- Also, if I'm correct, many 3D games use bounding box collision detection. Since I'm writing a 2D game, I would much prefer pixel-perfect collision detection (or some other, more accurate method of collision detection than bounding boxes). How should I go about this?

Yes, go with texture mapping. You can use the rectangular texture extensions to circumvent the need for power-of-two textures, although for El Ballo, in many cases we just stretched the textures back out - looked good enough.

Can't make any calls on QuickTime movies in a GLUT window, but if you can go with an AGL context, I have a lot of pretty good code from the good ol' El Ballo days that you can rip right out.

IMHO, don't bother with pixel-perfect collisions. It doesn't add a whole lot, and it is surprisingly tricky to achieve in an environment such as OpenGL (no quick access to the frame buffer). Instead, with a lot of collision rectangles. Instead of collision detecting thousands of pixels, you can easily get away with a hundred collision boxes per sprite, and chances are that you won't need more than two or three. Most sprites in El Ballo had only one collision box, El Ballo himself had a two or three. (Of course, the collision boxes were set per-frame in order to fit well while running!) In the case of the El Ballo game, these coll boxes proved to be a tad bit too coarse, so five or so would probably have been really good enough. And if you think that handling two-three collision boxes per frame of animation per sprite sounds prohibitive, then you really shouldn't do pixel-perfect.

There are some pitfalls that you'll fall into while writing you first OpenGL 2D game, but I think I have a pretty good tab on them all. Key words here are: "0.375f unit offset", "GL_CLAMP_TO_EDGE" and "premultiply alpha".

To answer your first question, glDrawPixels is very slow, since it must copy data to the video card every frame. Texture mapping, however, keeps the textured data on the video card and then displays it as needed on the textured quad. To answer your third question, collision detection is completely separate from the graphics engine, and has no bearing with OpenGL. For your second question, I have no clue.

Wowbagger Wrote:- First, I've noticed that there are a lot of recommendations to use texture mapping to get stuff on-screen. But I was wondering: what is the difference between texture mapping and glDrawPixels() in 2D games? Performance? (I'd like to avoid texture mapping because of the rule that the image dimensions must be a power of 2.)

I've never tried glDrawPixels() myself, but as I understand, it will be slower due to having to upload the image data to the GPU every time you draw, rather than just once up front. Also, you'll lose the scalability that textures give you.

As for the power of two restriction, you can get around it by using GL_TEXTURE_RECTANGLE_EXT, which works on everything newer than the Rage 128.

Wowbagger Wrote:- Second, is it possible to play QuickTime movies in an AGL window and full screen context via aglGetDrawable()? Or a GLUT window?

Don't know about this one for sure, but you might have some luck grabbing individual frames from the movie, putting them on textures, and drawing each one on a quad.

Wowbagger Wrote:- Also, if I'm correct, many 3D games use bounding box collision detection. Since I'm writing a 2D game, I would much prefer pixel-perfect collision detection (or some other, more accurate method of collision detection than bounding boxes). How should I go about this?

The sky is the limit as far as possibilities for collision detection are concerned - implementing pixel perfect collision detection the way you're probably imagining it might take a bit of fiddling, but you could most likely find a way to do it.

To answer your second question, you certainly can use Quicktime files in an AGL environment. Yeah, I think that aglGetDrawable() should work. I think it might be possible (?) in GLUT, though I'm not sure and I bet it isn't easy.

You can use QuickTime in an OpenGL texture regardless of whether you're using agl, CGL, NSGL, GLUT, SDL, or whatever.

You'll find ancient code here: http://onesadcookie.com/svn/repos/QTValuePak/ which should work anywhere (though somewhat inefficiently on Rage 128s due to the lack of EXT_texture_rectangle). It's a bit complicated and a bit slow.

If you can require QuickTime 7 (even on 10.3.9) you can use the new CoreVideo stuff to draw movies directly to OpenGL textures. This is very easy and very fast.

Thanks for all the support! A simple tile scrolling demo I wrote that ran at 20 fps under CopyBits() and QuickDraw now runs at 170+ fps under OpenGL. Mind-blowing...

Anyways, I had another question: is there an easy way to fade the stuff in the OpenGL viewport? Because it seems like overkill when the game is in windowed mode and the whole screen fades. I tried fiddling with the alpha argument to glClearColor(), coupled with a call to glClear(GL_COLOR_BUFFER_BIT), but the alpha value seems to have no effect.