Well, well, well…. this time I have screenshots!
Since my last post with screenshots I have discovered many things, the first and most important is that seems that our beloved John Carmack thinks (or thought) that OpenGL was great but that its default behaviors didn’t fit his mental map.
I was following David Henry’s tutorial to load this md5 files. Md5 had great advantages over other file formats, it’s easy, it’s documented and it is in text-form, so it is easy to read and see if you’re doing something wrong. Well, that tutorial is great, honestly, and there’s no “but”. I recommend it to anyone trying to load this file format. Take into account only two minor thing: Quaternion format and triangle orientation. But let’s explain all the process until I obtained a relatively good looking models :)
For some reason I don’t fully understand yet, Id’s quaternions are specified as q = ([x,y,z],-w). That led me to a very strange behaviour on the skinning of my mesh:
Why did I obtained such a strange model (even I have to admit I like it!) ? Well, MD5 my friends is a format full of surprises :). When the file specifies the skeletton information it only gives the vector part of the orientation for each bone. This is GOOD, you know, less data to read and well, we’re loading, we can spend as much time as we want, can’t we?.
So we have our vector from the quaternion and we need the scalar part. We know, because someone told us so, that the quaternions are unitary, so it should be easy, right?
Well, my friends… That would be in the WE_USE_THE_RIGHT_MATHS world, but let’s never forget that we’re dealing with John Carmack here, the man that made Doom and Quake, and probably the only man that can bend maths at will!
So if you ever want to load correctly MD5 quaternions, don’t forget to extract the w component using this:
Notice the minus sign :D
So once I noticed that (in fact once I re-read the tutorial :P) I corrected my loader and what I obtained was this:
WTF! Yeah i got correct orientations but what the hell were those pink meshes? Over time I’ve been adquiring some good practices that let me spot bugs or strange behaviours quicky, one of those practices could be stated as:
No matter if the material, mesh, sound or whatever asset is wrong, corrupted or unsupported, you MUST provide a fallback so the problems can be easy spotted and fixed.
And that’s what I did with shaders. After a brief discussion with shash about how to dispatch shaders to each material I did a quick and dirty shader dispatcher on the renderer. This function analyzes the material and depending on its properties it assigns a shader to it. Obviously I didn’t take into account all possible material definitions in MD5 material files… in fact it’s a shame but atm I only provide 2 shaders: one for diffuse materials, the other is that magenta shader :). So if the material has a diffuse map I give it a simple (very very simple) shader to texturize. Otherwise I give it the magenta. What’s the advantage of this approach? Well there are 2 main advantages:
- I am confident that the program won’t crash in case of uncorrect data or unsupported data
- I will see all geometry EVEN if i don’t have support for a specific material.
So I saw the player model there, it was there! It just have tons of other strange geometry overlapped. So I took a look to the MD5 file model again and I discovered something interesting. There were low poly shadow models there! Amazing! honestly this was totally unexpected, but at least this was easy to fix :) Those models used a material named “shadow” so I just ignored those meshes (my plan is use original material to generate shadowmaps so I didn’t need that geometry anyway).
Ok, so I removed the geometry and what did I obtain?
YEAH! a blue marine… damn! this was easy tho, the textures were TGA files, those textures are stored in BGRA format so I corrected that and I expected I would get finally the correct marine, right? Well, my journey was not ended… YET :)
Ok, something I had noticed when I obtained the blue marine was that the mesh had holes, and as you can see in this screenshot it even had the thumbs… well, reversed! Damn! I couldn’t believe it! :) I checked the depth func and was correct, I was loading the indexes correctly so where was the problem? Ok, shash helped me again (he made a md5 loader years ago and had faced these problem)… well the problem was that triangle order is Clockwise! There’s no problem once you know it, and probably this decision cames from quake 1 ages so I won’t start any kind of war here. I’m trying to become somewhat data agnostic so instead of doing a quick hack I just changed the order at loading time aaaaaaaaand:
Great! I got it! Well, the eyes and mouth look a bit “pinky” but I don’t support that material yet so….
With my loader ready to load new and shiny models I was ready to load… the zFat (doesn’t it has a filesystem like name?)
Yeah, perhaps is not very noticeable, but the tool is like flat colored, do you see it? Why is this? Well, file formats have plenty of surprises and they’re there, stalking, hiding, waiting to jump over you if you’re amusing. Well, in this case was because textures files in mtr files doesn’t have to have an extension specified. I had along discussion with Shash regarding if this was or wasn’t a good design decision. Obviously I still think it’s not, but I have to respect others’ point of view. Well, anyway, the format is specified this way, so I had to support it. And after coding a “if the file doesn’t have extension check if it exists for most usual image file extension files” procedure I ended FINALLY with correct models :)
Hehehe, well, after this I thought it would be nice to have it animated, and that is what I’m working on right now. This time i’ve taken a look to the files looking for usual weirdness, but this time seems that the files are nice enough :) But that is a whole different story and will be told in a different post! until then…