Home       About Me       Contact       Downloads       Part 11    Part 13   

Part 12: Adventures in OpenGL

February 10, 2011

In the last part, I was trying to speed up my rendering code, so that I can display a larger world. This was my last timing:

Opaque: 1.87 ms;   Transparent: 16.49 ms;   Total: 18.36 ms;   Frame rate: 54 fps

To make this faster, I needed texture arrays. I figured that would knock another 5 ms off the transparent time, which would be nice, but not essential. To get this feature, I could either go with DX 10, switch to OpenGL, or see if I could do everything myself in shaders with DX 9.

Since using OpenGL would potentially get me MacOS and Linux users, without losing Windows XP users, I decided to learn the latest version (I had played with version 1.1 years ago.) I picked up the Kindle copy of the OpenGL SuperBible and started working through it. That has pretty much taken the whole week.

Unfortunately, now that I have the demo sort of running under OpenGL, I get this timing:

Opaque: 1.95 ms;   Transparent: 27.19 ms;   Total: 29.14 ms;   Frame rate: 34 fps

As you can see, the transparent time is much worse than the DirectX implementation. Since there are only a few API calls involved, I'm not sure what to try. I still have to change the code to use texture arrays, which will save me at least some time. If there's a high overhead for all OpenGL API calls, it could save a lot of time. I'll keep experimenting with it.

I tried the code on my old Windows XP machine and it ran fine. That encouraged me that I would not lose any XP users. But then I tried it on my laptop, which runs Windows 7 and has an ATI Radeon HD 3450 display chip. It complained that the driver only supported OpenGL 2.1 or something.

I upgraded the drivers off the ATI site (the Dell site had nothing) and the new version said it supported OpenGL 3.3, which is what my desktop runs. Unfortunately, the shader compiler crapped all over the shaders that worked fine with the two Nvidia displays. After some cleanup, I got three of the four shaders to compile and run. The last one uses "Rectangle Textures" (for my cursor pattern), and apparently that feature is not supported by ATI.

This is a real problem, since it means I can't count on a particular feature set when I develop the code. I'm not sure what to expect under MacOS and Linux, or on different display hardware. Sigh. I really find it kind of inexcusable that ATI and NVidia support a slightly different syntax for the shader language. Didn't the OpenGL committee write an exact grammar for the thing?

I have installed xcode on my Hackintosh and compiled one of their OpenGL samples. To port the demo over, I just have to plow through all the MacOS development documents. I'm not sure if I will do this right away, or work on the Windows version a bit more.

If my interest in OpenGL lasts long enough, I intend to port this to Linux as well. Can you Linux users point me to your favorite IDE and tools for C++/OpenGL development?

That's Quite a Pile...

Since I don't have any videos or images to show you this week, I'll just BS a bit about writing the demo. Going through the OpenGL exercises, it struck me how much stuff you need to know to do this project the way I'm doing it.

  • The code is written in C++, so you have to know that. But you also have to know straight C, and be pretty familiar with the preprocessor. That's because C++ coding being what it is, fairly often the debugger is going to drop you into some library written in C. The "glew" and "freeglut" libraries supplied with the SuperBible are both in C. Both have sections that are a maze of macro references and #ifdef's to handle multiple platforms. If you can't read this code, you'll have a hard time knowing why your program has crashed in the library.

  • You need to know at least some Windows/MacOS/Linux programming, not just to get things initialized properly, but also to handle input, sound, multiple threads, critical sections, etc. This kind of code is not trivial to debug.

  • You need to know at least the basics of algebra and trigonometry to handle coordinate spaces in 3D, and know what all those dot products and matrix multiplies are doing.

  • The OpenGL interface is simpler than ever, since they've shifted over to shaders for everything, but there's still a bit to learn there.

  • And finally, you need to know how shaders work, which I'm still learning.

On top of being difficult to learn, this whole stack of software, from bottom to top, is famously brittle and unforgiving. Even after decades of experience with C++, there are still times when I get an error message from the compiler and think "what the hell are you complaining about now?" Do anything wrong in the Windows or OpenGL API and your program crashes without explanation.

The most trivial errors in your code can set you back for hours. When I finished my first pass at the OpenGL version of the demo, I fired it up and got -- a black window. This was annoying, since I had debugged all the graphics code in a smaller standalone demo, and the rest of it was the same as my DirectX version. I knew I was generating the right list of vertexes and indexes, and setting the right projection and view matrices. So why no output?

I stepped through huge amounts of the code, put in more and more debugging statements, checked the OpenGL return codes in more places, and couldn't find any problem. As far as I could tell, it was doing everything correctly. After being up all night, I finally called it quits at 5am. And just as my head hit the pillow, I thought "Mipmapping!" and got out of bed again. It turned out this was the problem.

"Mipmapping" is when the library produces several lower-resolution versions of your texture image, for use at larger distances. So for a 128 by 128 texture, it will also generate 64 by 64, 32 by 32, etc. versions. I had forgotten to put in the call to generate these, which meant the lower resolution versions were all black. So my code was doing everything right, but painting black triangles over other black triangles, over a black background! Sigh...

I can't complain that this software is unusually hard to use -- it's only taken a week to work through the book, and I haven't had any really huge problems. I had some confusion over how index buffers work, and this nasty mipmapping bug, but other than that, it's been smooth sailing.

Kid Stuff?

I'm making progress on the project, but I still have to compare this to what I was dealing with in Junior High when I learned programming, back in 1971. It was very unusual for any kid back then to have access to a computer, much less learn to program it. But programming that old mainframe computer was easy in comparison to this. All I had to deal with was a single programming language (not C, C++ and shader), with almost nothing in the way of an API. You just wrote text to a typewriter-style terminal.

My first programs were games. A card game, a "star trek" game, and a really, really bad chess game. I would think a kid today would also want to write a game. Since he's been playing games since he could push buttons on a console, he probably wants to write a 3D game. But he can't just write a simple program in Basic anymore. This huge stack of software and a couple of thousand pages of tutorial and a bit of math are what he has to deal with!

And to write a "real" game, with a large world and a lot of things going on, he's going to have to be a pretty decent programmer, not a novice.

Now I know there are answers to all of this. First, you could just use an existing game engine and not even try to write code at this level. Just as no novice programmer sits down, designs a programming language and writes a compiler, perhaps it's completely unrealistic to expect anyone starting out to write OpenGL shaders.

Second, most programmers (nearly all programmers!) would use more libraries than I do. I was always infamous when I was working for writing my own frameworks. It's not that I have to do everything myself, but I do hate debugging code I don't understand. And I am genuinely curious about what is happening under the covers. Since I code fairly quickly, it's always been easy for me to just write what I need, rather than dragging in huge packages with poor documentation, odd interfaces and bugs.

Third, there are other languages to write in. Perhaps some of you work in the games industry and can tell me if people are still writing in C++? Are most games just done by artists/designers who use an engine written by a few hard-core C++ programmers? Are "indie" games done the same way?

Given my skill set, I'm comfortable with the approach I've chosen here -- a big C++ application doing graphics at the lowest level. But working through that OpenGL material, I did wonder if perhaps I've chosen a hiking trail through the mountains, when there's perfectly good highway down below...

I also wondered if any kid anywhere still picks up a programming book and writes something great, or if we've made it impossible to do that?

Home       About Me       Contact       Downloads       Part 11    Part 13   

blog comments powered by Disqus