Archive for July, 2008

Keyboard troubles in 2008

Monday, July 7th, 2008

Bug reported in KP :

“I can’t jump while moving backward + left or right! However the jump works when moving forward +left or right”.

Well, change your keyboard. After investigation, this is neither a DirectInput nor a Win32 problem: it’s a low-level keyboard issue. Some keyboards don’t support the key combination, period. Others, USB keyboard in particular, seem more friendly (and the bug doesn’t happen with them).

Quick test to see if your keyboard is “bad”:

  • run this exe from the DirectX SDK: \Program Files\Microsoft DirectX SDK (August 2007)\Samples\C++\DirectInput\Bin\x86\Keyboard.exe
  • create an Exclusive, Foreground, Immediate device
  • press keys S, D and Space simultaneously.

If it says: “Data 0×1f 0×20 0×39″ you’re good, go play KP. If 0×39 is missing, you’re screwed. Like me.

…I seem to remember this wasn’t an issue on an ST, but I’ll shut up.

EDIT: this is really a low-level keyboard issue

Debug console for Win32 app

Monday, July 7th, 2008

I keep forgetting this one so let me post it once and for all. Adding a debug console to a Win32 app takes 4 lines of code.

if(AllocConsole())
{
freopen(”CONOUT$”, “wt”, stdout);

SetConsoleTitle(L”Debug Console”);

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
}

You can then printf your way out of trouble.

Blast from the past

Sunday, July 6th, 2008

My old Atari ST has been locked in a box for years. Today, out of the blue, I decided to open the box again and check the machine was still working. My first surprise was that its color changed. I don’t know what happened but the light grey disappeared and got replaced by a dirty, sick-looking, brownish yellow. I have no idea how it happened, but it looks nasty.

The second surprise is that everything works like a charm - machine and disks. I expected both to be dead by now. But no, more than 20 years after I bought it, the Atari ST still works flawlessly. I watched a few of our old demos and I now realize one thing: our taste sucked. Check out those beautiful RGB colors in “Inverted Landscapes”, one of our first screens…

Mesh granularity

Tuesday, July 1st, 2008

Idea to try: one region = one mesh.

Current system:
- a level is made of different regions connected by portals
- a portal is a convex polygon
- a region is a collection of meshes
- a mesh is a collection of “subsets”. Each mesh has a single PRS transform and is a single object in 3DS MAX.
- a subset is a collection of triangles sharing the same render states (same material).

Currently, things are exported as-is from 3DS MAX, and each region contains several meshes, depending on whatever is in the MAX scene. Visible objects are batched, and sorted to minimize the number of render state changes. However this may not be necessary: we could use the “static batching” that happens for each individual mesh instead, the one creating subsets. We just have to merge all the meshes of a given region together, ending up with a single mesh per region.

If the regions are quite small, i.e. if it is possible to see “all” meshes of a region from a particular viewpoint, this looks like a good idea (following the “optimize your worst case” strategy). We save memory by reducing the number of “meshes” in the system, we save CPU time on culling, batching, etc.

If the engine creates one physics mesh for each render mesh, it might also have some benefits. It certainly saves memory, minimizing the cost associated with each “object” within the physics engine. It also reduces the stress on the broad phase. However it puts it on the midphase (basically OPCODE), since the whole region is now a huge AABB-tree. The old “RAPID vs OPCODE” tests showed that AABB-trees are not too great when a small object is fully contained within a big scene, but on the other hand temporal caches helped a lot for this case, so it might be ok in the end.

Now the only issue with this is probably when you have a room with several open doors, each of them being a portal connected to a different region. If you stand in the middle of the room looking at those doors, you end up rendering all the regions even though a small part of them is visible, whereas before only the first meshes of each region would have been rendered. So you made your worst case worse, in a way.

——–

Not merging meshes at all and keeping the same organization and the same number of objects as in MAX does work, but it puts the burden on the artists, and on the batcher. But even if the batcher does a perfect job, you still waste memory associated with individual meshes. In ICE, sizeof(Mesh) is something like 500 bytes or more, which I know is too much, but that’s how it is now, and a lot of professional engines have worse than this. With ~1000 meshes in a single region,that’s ~500 Kb lost per region: not good. Plus, the batcher is never “perfect” anyway, i.e. it has a runtime cost.

Merging meshes by material regardless of spatial considerations doesn’t work. It makes things easier for the batcher but it kills the physics.

A good alternative is just to cover the region with a fixed-size grid, assign triangles to grid cell (regardless of their original mesh), and create one mesh per cell. It keeps the number of meshes under control, it’s physics-friendly, and also culling-friendly. The main drawback is when the physics does a convex decomposition and relies on it to have good collision response. You can end up with a perfectly flat plane cut to N different, unconnected physics meshes - and bad collision response when an object slides from one part of the mesh to the other.

You can always completely decouple the physics & graphics representations, but it’s a pain to manage. Probably the best option though.

shopfr.org cialis