March 26, 2013 Leave a comment
A couple of months ago I discovered Pyglet, which is basically an OpenGL interface for Python. I experimented with it, figuring out different features. I had never really worked with OpenGL before, and the little bit of experience I had was limited to translating GLUT spheres (for an N-body simulation for my Parallel Computing class).
My exploration into Pyglet was a two-pronged attack. On the one hand, I had to learn how to use OpenGL, and on the other I had to learn Pyglet’s idiosyncratic diversions from standard C OpenGL. Fortunately, there is a wealth of tutorials and explanations on the Internet regarding OpenGL, and Pyglet is fairly well documented.
However, there is a caveat to exploring a new tool: debugging becomes much harder. When your code stops doing what it is supposed to, you have no idea whether the bug stems from a mistake in your code, or a fundamental error in your method. Moreover, your method may work in theory, but you are using the new API incorrectly. Since there is no way to test all three of these possibilities at once, you have to assume two of them are correct and look for an error in the third. If you pick wrong, you can spend days looking for a bug in the wrong place.
For instance, I was writing code to find the ray originating from the camera and passing through a point on the screen where the user had clicked. The issue here is that although you know the location of the click with relation to the window, you don’t know where it is in world space. Well, I went through 3 or 4 methods for finding the vectors in world space that corresponded to the vertical and horizontal directions on the screen. After that the problem becomes trivial.
In desperation I started printing out random things in the body of my code. I realized that two variables which should have been the same were very different. It turned out that when I found the location of user click in world space (which was stored as a vector), I was accidentally normalizing it.
I had assumed my code had no careless errors, and had instead blamed the bug on my method. In reality, I doubt there was ever a problem with my method. Instead, the problem had always lain in the three lines of code that I considered the “trivial” part of the problem. While it was quite trivial, that triviality also protected it from proofreading. After wasting a good 4 or 5 days on the problem, I have learned my lesson: there was absolutely nothing I could have done about it.