Finally, I'm ready to make another entry for this journal. I've been really looking forward to it. But I do not wish to add irrelevant progress updates or personal messages to this journal. Instead, I will set goals for each next entry. I believe this approach is to my advantage.
I've been working on my ideas for this game for quite some time already. Only after playing around with cartoon rendering techniques, and coming up with an elegant method for my game, I was willing to start my journal. The only thing missing from my (graphics) list were shadows. After doing some research I was sure I wanted to use stencil (or volumetric) shadows. They proved to be somewhat difficult to implement nicely though. Certainly, without the willingness to use OpenGL extensions (and sticking to OpenGL 1.1) this is a bit tricky. Furthermore, finding all light source facing triangles of each model (as well as creating a shadow volume for them) didn't sound like fun to me. I pretty much wanted to find a solution to this problem, since I knew that shadows would make my game look much better. Finally, I came up with a relatively nice and clean solution that involves only a few calculations for the CPU and a bit more on the GPU. I will explain this in the next section. Please note that I haven't tested it yet.
OBJECTS & MODELS
Some time ago, I made a list of requirements for the graphics in my game. Obviously, there will be static 3D models (I will call them 'objects') for all sorts of things. Additionally, some models will have parts (objects) that should rotate relative to each other. This can be said for about each game there is. Well, in addition, I want my game to be able to generate models for (human) characters itself, based on a few parameters. I want to have some gradations between normal, fat, and tall, as well as muscular men and voluptuous woman, with clothing to match. And of course, I will simply use matching vertices over a few models to do this.
The shadows that a model will cast on intself and it's environment will be encoded in the models too. To do this, I will first start to look at an object's complexity, then I will define some planes of vertices for the object (like cross-sections). These can be combined to cast a good shadow approximation of the object's shape. I will start drawing the object by putting vertices on these planes. Sometimes simply connecting vertices into triangles between different planes will suffice for an object. In other occaisions, extra vertices will be required. A bonus to this approach is that it resembles building a 3D-model from (more simple to draw) side-views. Simply drawing a line through all vertives on a single plane will give a strong visual hint of the object's appearance. This approach should work pretty well, especially on low polygon models where there are not too much 'floating' vertices required between the planes.
I will use indexed vertex-arrays for rendering. I will store vertex, normal and color information, and combine vertices where I can. The first vertex of an object's array is reserved for rendering shadows. Now when it's time to render shadows, this vertex has to be calculated. It's function is to provide a focal point for a triangle fan for all vertices of a particular (shadow) plane of the object. This fan, which is also rendered using (stored) indices will form a shadow volume for each of the planes. The information stored is simply all indices of the vertices on a plane, that combine together with the focal point to form a triangle fan shadow volume. If the focal point if far away enough, it'll make the volume appear 'straight'. Taking the relative orientation of an object's shadow volumes into account, they can be rendered in pretty much the same way as in the z-pass or z-fail algorithms, simply by adding or substracting the stencil values (if their orientation is not taken into account, different volumes will stencil each other out). Depending on a volume's orientation, values should be either added or substracted. Switching cull faces should also work.
So much for the theoretical work. Now on to some more practical issues.
THE FIRST STEPS
Creating a game involves lots of things. As with any program in any programming language, adopting a protocol for naming conventions is a good place to start I guess. I took quite some time setting up this protocol. I also wanted a very uniform structure and layout of my files, and will spend a considerable amount of time maintaining that. With only about 2000 lines of code, I can already clearly see the benefits of this. When you know where to go; the next things are functions and classes and such, and where to put them. It really pays off to think a lot about that sort of things.
My game will be window-based, and does not require split-second user interaction, so I will need to proces some Win32 API messages. I defined my own game events, enclosed them in a structure and put this and all window-related code in one file. I can now easily switch between different event handlers by changing a pointer. This was a very good first and nescesarry step. After this, I realized that I could speed up development time by writing some tools that can operate while I am testing my game. To make this possible I will need a user interface with controls, and an easy way of setting it up. I therefore added another project file that defines these controls, and handles all game events for them (I knew my events would come in handy). Here are the controls I have so far:
I've got simple labels, buttons, edit boxes (with different input filters for integers, floating point numbers and filenames), list boxes (that can additionally display colors), and some nice HSL color selection bars. The mouse pointer is changed appropriately over controls and the scroll wheel is used with list boxes. Relevant events are routed to event handlers for each control. Other controls can be implemented with a few lines of code, and an interface is set up very easily too. Of course, there is also a control that can be used for more serious rendering (that's the one with the diagonal line). Lots of tools can be created with these controls, but there are some limitations however. Controls cannot size dynamically; but hey, who cares?
My HSL color selection bars are the most elegant method of selecting a color I have seen. At all times, the color under the slide-button on all three bars is equal. Changing its position on one bar changes the colors on the other bars. This is very comfortable when trying to find 'matching' colors. The fixed-width font is based on the C64 font. :)
ps. Using the Win32 API: does anybody know how to change a window's caption, without changing the text in the associated button on the taskbar? -Thanks.>