Introducing Sphere World

Chapter 4 introduces Sphere World, an app that progressively improves as the chapters roll by. This first version simply draws the ground as a gridded plane, with a spinning torus at the center, orbited by a small sphere. Fifty other spheres are distributed randomly across the plane (they’re all at the same height), and the user can use the arrow keys to move around.The torus and all the spheres are drawn as wireframes in this version.

Getting it working required fixing the usual minor bugs, plus three interesting issues. I had to look up how to deal with keyboard events, and in doing so discovered that the constants for the arrow keys (like NSUpArrowFunctionKey) didn’t match the keycodes that came in when I pressed the arrow keys. I hard-coded the relevant values, but I need to find out how it’s actually done to get away from having “magic numbers” in my code. I also forgot at first to override acceptsFirstResponder to return YES in WorldView. That resulted in the app beeping at me with every keystroke, very annoying.

Next up, the randomly drawn spheres didn’t appear. The problem turned out to be that the ApplyActorTransformation method of the book’s GLFrame class was producing an all-zero transformation matrix. That turned out to result from the GLFrame instance having zero vectors for the up and forward vectors.

Those should have been initialized to unit vectors in the constructor, which got called once, apparently without setting the up and forward vectors for any of the spheres. Since the spheres were in a static array, I thought that they would be initialized automatically, without using new like you would do for a pointer-based instance. At any rate, I set the vectors (to their defaults!) when initializing the locations of the spheres, and that took care of things.

I also spent some time figuring out how to make the animation look smooth. The first idea was just to make the incremental change in position or angle smaller, which helped with forward and back motion, but didn’t do much for rotation. The second idea was to increase the frame rate, which didn’t do much except change the speed at which the torus and orbiting sphere moved.

The idea that worked was to move or rotate a bit with each frame. I checked how often the drawRect: and keyDown: methods were being called when holding down a key for autorepeat. That turned out to be five (occasionally four) calls to drawRect: per call to keyDown:.

Based on that, I had keyDown: set a value for a counter (positive for forward or right, negative for backward or left), and then moveObjects (called from a timer) would check the counters. If they were non-zero, it would decrement or increment the counter toward zero and move or rotate appropriately. That gave swift smooth motion: very nice!

Now on to chapter 5…

This entry was posted in OpenGL. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s