Tex2D Rotating Header Image

engine

Status Update… or what happens when you start pulling the thread

Ok, I know, I said I would implement sound, and I swear I started, but I can explain what happened and why I’m still without sound.

For each kind of data (i.e textures, materials, loaders, etc) I had a manager. Each manager was a singleton, and after coding the Sound manager I said “Dude! I have tons of singletons, it’s time to change that!”. And that’s what I’ve been doing. I’ve centralized managers, factories and containers under the Engine’s hood. To ensure there’s only one instance of each manager I’ve tangled a bit managers and engine :). It’s something like this:
An excerpt of IManager’s code
class IManager
{
public:
IManager(int type, Engine* e); //Constructor
virtual int GetType() = 0; //some RTTI
...
};
// Adds the manager to the engine
IManager::IManager(int type, Engine * e)
{
e->AddManager(type,this);
}

An excerpt of Sound Manager’s code
class SoundManager : public IManager
public:
explicit SoundManager(Engine* e); //Constructor...
virtual int GetType() { return MGRT_SOUND;}
};
// Adds the manager to the engine
SoundManager::SoundManager(int type, Engine * e) : IManager(GetType(),e)
{
}

So as you can see, it’s engine (called from IManager::IManager who decides what to do with the manager’s instance). In my case I stored it in an array.

So once I had all managers de-singletonized (?) I thought:”mmm, I’m not sharing data”. Yes believe it or not, I was loading models, animations and textures as many times as they appeared in the data files. So well, just some more coding following the same schema I had used for managers and well, at the end of the night I was sharing data correctly.
And this morning… I’ve woken up thinking “Ok Toni, so you’re sharing data but, do you know how much memory is your application consuming?”. At Insideo, shash had coded a memory checker, and I’ve thought that doing something similar I could know, at runtime and with a per frame granularity, what was the ammount of memory I was using.
I’ve searched on the internet and I’ve found 2 sources one at flipcode (RIP) and another at CodeProject. I have adapted to my needs and at the end of the day I was tracking the memory consumption…
To my surprise my application was a RAM eater monster :| just loading de imp animation and it was taken as much as 78 MB! WTF!!

78 MB!! The RAM eater monster attacks!

78 MB!! The RAM eater monster attacks!

The first think I’ve thought has been: “textures, probably I don’t release the texture data”. So I’ve checked it, and indeed, I wasn’t releasing it. I fixed it but as I expected I didn’t had a big gain, after all currently I’m only loading 5 textures :).

75 MB the RAM eater monster is on diet! :D

75 MB the RAM eater monster is on diet! :D

So… I’ve been thinking… where do I have tons of data and it’s not released? Where? Where? Obviously it was on the loaders, so I just simply added a Reset method to all loaders, call it after loading and that’s it! :)… And you can be wondering :” And where were those dozens of MB?”. Well, the md5 material loader was keeping a table with a translation from material name to material file and some other info. And that table was consuming 70 MB!!

5MB ! The Ram Eater monster is now thin like a ballet dancer!! :D

5MB ! The Ram Eater monster is now thin like a ballet dancer!! :D

Well, now I have the Ram under control, and I suppose now it’s the momment for sound. The journey of this 2 last days has been interesting, reallocating some classes and studing how to keep track of memory has taught me some good things I didn’t know about memory allocation and new and delete operator overriding :). Probably this will evolve in a near future to some kind of memory allocation manager and custom allocators and all this stuff I’m willing to learn :).

Well, it has been a good weekend, stay tuned!!

Status update

Two status update on the same day? GOSH I’m crazy! The world is ending! Penitenciagite! :P

I’ve just followed shash’s advice and implemented frame interpolation. Obviously it didn’t work the first time I tried, but the second. As always I’ve recorded the progress so you can enjoy and laugh.

Implementing frame interpolation was really easy but if your interpolation value is greater than 1.0 you get things like this


Once I changed that i got a nice interpolated animation


And now, once this is completed… it’s time for sound!

Stay tuned!!

Status Update

As I said on my last post, I was pursuing animation, and guess what: I have it!

Even when I haven’t implemented frames interpolation yet the animations look funny. So let’s start with the usual postmortem of what went wrong.

First I started parsing the md5 anim files, and guess what I don’t like it either. It’s not hard to parse, it’s just nonsense. It starts with a hierarchy and a base frame, well, everything seems ok until here, right? But then you have the frames, defined as a series of floats that, with some kind of obscure craft applied over the base frame and with the information in the hierarchy gives you the skeleton for the given frame. Sure it works, sure it has few data and sure: WHAT THE HELL WERE YOU THINKING OF? I think, honestly, that it would have been simpler to have an skeleton for each frame, easy and simple. Why do people think that being clever is ALWAYS the right way? Sometimes a simpler approach makes life easier :)

Well, once I have it loaded I faced another decision: coupling an animation and a model with a custom file or being a real macho man and loading the doom 3 def files? Obviously I’m a macho and def files was the way to go :).

And what are the def files? Def files for models at least define the entity informatio, in particular you can find there for each model what mesh and animations it uses. I have to say that this is the first file format that likes me :). It’s simple and does what it has to do. For each model defines a mesh and a series of animations, and for each animation what events applies and in what frames. Wonderful! :)

So I made a little loader for it and here’s the result:

Amorphous blob from the pitt!

Amorphous blob from the pitt!

WTF!?! I had a correct skinning system! What was happening here? At least I have to say it was indeed animated :)


YouTube Link to

YEAH! I have videos, thanks to glc capturing application, fraps-like for GNU/Linux. Well, it looked really weird, didn’t it? So I checked the def file and I discovered that it contained 3 imps models, so click click click I just hacked the loader a bit to have them separated and what did I got? Well, this:


YouTube Link to

Which… well, looked at least strange :) The first 2 imps remind me that Edvard Munch painting: The scream

I didn't know Id inspiration for imps came from expressionism!

I didn't know Id inspiration for imps came from expressionism!

Well, once they were separated I was wondering what failed, because the only model that was animated was the right-most one, but in fact it wasn’t properly animated but somewhat convulsing :S.

Well, it was due 3 little bugs

  1. Quaternions, my friends, are composed of 4 floats, and when I was reading frames I was just missing one component
  2. When I readed a frame and I send it to process, I only processed it when it had movable parts (that is, was different from the abse frame). But the base frame wasn’t processed so I had to process the base frame to get good results.
  3. The tutorial I was following said something like “I assume that parent index < current index so parents are always processed”. So did I, and when I was processing a frame I assumed that parents had been previously processed. Well that’s simply not true, so I had to do some adjustments to have a correct processing.

With all that fixing here and there I ended with this:


YouTube Link to

It was ok, just that it wasn’t moving due the first 2 models had an animation with 0 frames, nice isn’t? So i did a little more fixing-typing-hacking to cicle among all models’ actions to get this:


YouTube Link to

And finally I decided that watching a single model was nicer, so I loaded a single model and put a better camera:


YouTube Link to

So, at the end I got the model animated… but with no sound, and wouldn’t be nice if it had sound? Well, that’s the next thing to do! Stay tuned!

Status Update

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:

More abstract art!

More abstract art!

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?

w = sqrt(1-x^2-y^2-z^2)

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:

w = -sqrt(1-x^2-y^2-z^2)

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:

Pink and blue marine

Pink and blue marine

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?

The smurf marine!

The smurf marine!

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 :)

Opposite thumbs!

Opposite thumbs!

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:

This marine has super powers!

This marine has super powers!

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?)

Almost correct, excepting the tool!

Almost correct, excepting the tool!

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 :)

A rotated imp

A rotated imp

zFat with strange pink balls in his hands!

zFat with strange pink balls in his hands!

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…

Stay tuned!

Status Update

Ok, I don’t have screenshots this time :)

I’ve removed another dependency, this time the affortunate class that was removed from my software wash fboClass. Shadower, the first incarnation (and lucky for all of us now is dead, buried, burnt and… everything) of this engine used several external classes (that is not coded by myself), including lib3ds, glm and fboClass.

fboClass is a wonderful collection of classes and utility functions just to handle FBO, and it was nice to use, but now, with that engine overhauling I thought it would be nice to have my own fbo class, and integrate it with my graphic driver architecture.

Well, one less. At the end I would like to have only SDL and Devil as dependences, well, if I add sound I suppose i will have fmod or openAL too, but that’s another issue :)

The simpler the better

You know, graphics is amazing, graphics are interesting, challenging, funny and rewarding. I love reading siggraph papers as much as any other out there, but there’s a thing that I love the most: designing and coding those little helper systems that make your life easier.

Today, for first time in my blog, I will start sharing pieces of code of that pet engine I’m coding at home :) And today’s piece is the tiny Information Item System.

You know, many times you need to get runtime information from the application, information like observer position, memory consumption, frames per second or even runtime profiling information. In previous implementations I had hardcoded that information, that was clumpsy and not very scalable to be honest, so now I had the opportunity to start it all again I decided to do it better, scalable, datadriven and with all those fancy properties that are so cool today.

The idea behind it is very simple, and the system itself is stupidily simple so let’s start explaining it:

I’ve decided that every piece of information I need can fall in one of those 2 categories

  • Text: The information can be retrieved as a string
  • TextTree: The information can be retrieved as a tree of strings

In fact, to be honest, the TextTree was added lately in the design phase, when I realized that profiling could be added to this information system. But having that in mind the design was as simple as it can be.

Every information item would have this properties:

  • There would be only one item for each category (no duplicity)
  • Each item would be capable of gathering all the information needed, process it and format it.

So with that in mind I ended with this UML diagram

Info Item Class Diagram

Info Item Class Diagram

Well, I know, it’s stupidily simple! And of course, at this momment I only need 2 InfoItems (and those are the ones that are implemented).

All this items are stored into a singleton named, let’s be original, InfoItemManager. This is the only place where this info items should be stored.

Info Item Manager

Info Item Manager

Now, how all this thing work?

Pretty easy, on Init time the manager registers all the info items.  Later, on update time InfoItemManager will call to update on each info item, there each info item will process and generate the message that it will return. As I told you, it was easy :)

Ok ok, you will say, the info items have the info, but that doesn’t mean I can use it. Indeed, the information is there, you only need a way to access to it, right?

Each one of the InfoItems have 3 key methods: GetId(),  GetType() and GetInfo().

  • GetId returns the Id type of the info item (FPS, POSTION, OBJECTS and so on)
  • GetType returns if the Info Item returns a single string or a Tree
  • GetInfo returns an union, with a char* in case of being a string or … well, at this momment it only returns that

So here it goes, in case you want to access to, let’s say the Position string you could do something like this

InfoItemManager::GetInstance()->GetInfoItemId(III_POSITION)->GetInfo()

That would return you an InfoItemValue union, that, knowing that III_POSITION returns an string well, you can use it directly to write it down wherever you want.

Well, the code of the manager and the info items can be downloaded here . It’s a bit dirty and such, and it’s exactly how it’s working in my engine. You will notice some weird way to get the position on the InfoItemPosition, and you will see that InfoItemFPS does the actual calculation of the frames per second, but it should be pretty easy to adapt it to any engine (after all they’re only 3 classes!)

Further improvement

Right now this design does exactly what I need, but that doesn’t mean it can’t be improved does it?.  Here are a few:

  • Allowing not returning only strings, but actual data, like vec4.
  • Ensuring that there’s only one instance for each infoitem. That is, in fact pretty easy. Lately, in some of my class hierarchies I’m starting to add an static method named Create in the top most base class. This method takes the type of the object to create and returns an instance of the corresponding class. Well specifiying a Create method in InfoItem we could check if InfoItemManager already has an instance of that method (and it should, Init() method in manager ensures that). If the instance exists we only have to return that instance, otherwise we can create an instance, register it in the Manager and return it.

Well, that’s all, a pretty easy, simple, little example of code. The next one, I’m still thinking if it will be the Graphic Driver or the widgets system.

Stay tuned :)

A rant!

Ok, what the hell were id software’s designers thinking about when they plotted the material files?

I was happy this morning, you know, with my models loading and that things, and i’ve said “hey, wired models are cool, but properly textured models are cooler!” So this noon i’ve started to look to how materials are handled in this otherwise, pretty simple file format.

Imagine my surprise when i’ve found something like:
shader “path_to_a_shader/shader_name”
and only that!

I’ve thought, ok, there must be a file named “shader_name” so I can make an n:1 relation, easy, right? Well, no. Don’t get me wrong at Insideo we had something similar to, each mesh had a reference name to a material, but there was 1 file for each material!

At id thought that it was a bad idea doing it that way, that probably having tons of files would be a bad idea (and I can agree with that). So their solution? having files with a bunch of material definitions there, you can find something like a file named “chars_common.mtr” with that “shader_name” definition in it!!

WTF! ok, I’m ranting just due the frustration of something that could be better. I mean, was that hard to have some kind of translation table? something like “you can find shader_name in the file chars_common.mtr”? In theory what you download with the demo are somewhat production files, aren’t they?

Bah, I suppose they have that table, but they keep it somewhere hidden :) :). Well, as I don’t find it, this means I will code that table tomorrow morning. Now it’s time to go to see how  F.C Barcelona beats Manchester United and we become champions.

Status Update

Yesterday was a happy day :) As I stated in my previous post, I hadn’t tested any of all the code i had written, so yesterday (and the day before yesterday, and in fact the whole weekend) I was commited to test the loader and the shiny new math library.

Obviously it had bugs, several bugs. I spent a whole day with the quaternion class, unit testing it, and testing and testing again. I’m not able to visualize quaternions so it’s hard for me to test them or knowing what to expect when i set a watch in a quaternion during a debugging session :(.

I’m a firm believer that when you’re going to test something, start with simple cases, and later on, you can test harder and more complicated things. So being sure that quaternions were wrong, and that if i tried to test the md5 models i would be completely lost, on monday I decided to add the “feature” of being able to generate simple geometry on the fly (currently only cubes :) and start the testing session.

Da cuba man!

Da cuba man!

Yeah, i know, it’s not impressive, but it helped me to test if rotations were working ok (which weren’t) and if translation obeyed my commands (which, surprisingly, didn’t either). Once everything seemed ok I thought “Toni, it’s time to load the jeep md5 model” . And I did, and … the result was less impressive, or probably for some abstract artists, pure art :P

Abstract art

Abstract art

Ok, there was some problems there, so I went back to quaternions and they were ok, I looked at the loader, and seemed ok, I even wrote several debugging functions to get the state of the mesh… everythin ok. So where was the problem? Mesh indexes seemed to be completely messed up :| so I fixed that and…. Voilá

A wired jeep

A wired jeep

Ok, it’s not shaded and … it looks a bit… clumpsy :) but I like it :) now I can move forward to my deferred renderer, but first I will need to import md5 materials :)

And here end my status update, stay tuned!

Status update

Well, interesting times….

I’ve just removed a dependency :) GLM Math library is an excellent templated library, honest, use it if you want power and a nice syntax. Unlucky for me, I was using an old version (from 2007 IIRC) and it had several bugs. I decided to update the library to its last version, downloaded it, and then … then I realized i only use three math classes: Vec4, Mat4 and Quaternion, so I coded those classes and now i have one less dependency :)

I want to be honest here XDD I haven’t tested them and even when I will use unit testing on them (thank you for point me that possibility shash ;) I’m pretty sure that it won’t work on the first try hehehe.

More! Yes I have more! :D The md5 loader is almost complete, and working… well, after changing the math library, perhaps it’s not working anymore, but it’s there, waiting to load shiny md5 models! :)

Finally, I designed a useful notification system :) I use it in order to gather information from the application, I’m preparing a full article on that because I think it can be useful to somebody :)

And that’s all.. stay tuned :)

Things to do: The Master Plan

This are the things i have to do to be happy again.

Currently the engine still has a strong component system (which affects to its speed) and supports PCF and SSAO with a forward rendering. The idea here is convert it to a deferred renderer, and these are the steps

  • Logging System
  • Ogl Loader
  • Md5 loader
  • Calculate Normals, tangents and bitangents for Md5
  • Create new shaders
  • Deferred Shading
  • Jackpot!