Thursday 17 September 2009

Command Engine


The CommandEngine class contains the core of my command console. It is basically a simple script interpreter, which can execute methods and read/write properties. Methods can be nested, and can return any type and have any parameters.

You can make a static property or method available to the engine by sticking the [Command] attribute onto it. The engine will scan the assembly and pick out all these methods and properties.

[Command]
public static string Print(object o)
{
    var s = o.ToString();
    Debug.WriteLine(s);
    return s;
}


[Command]
public static string Hellp { get; set; }


[Command]
public static int Framerate
{
    get { return fpsCounter.Value; }
}

Adding instance methods and properties has to be done by calling the AddCommand or AddOption method on the engine instance respectively.

engine.AddOption(player, "Position", "Player.Position");


[Command]
public static Vector3 Vector3(float x, float y, float z) 
{ return new Vector3(x, y, z); }

Once you have some commands registered, you can call them with the execute method:

engine.Execute("Print("Testing"));
engine.Execute("Print(Framerate)")
var helloString = engine.Execute("Hello").Result;
engine.Execute("Player.Position = Vector3(0, 10, 3)");


You can download the source here.

Wednesday 16 September 2009

Materials and Render Phases

Materials and Render Phases are going to be the core of my renderer.

A material defines an effect, any render states it wants set, a set of constant effect parameters (e.g. a texture), and a set of public application-settable effect parameters (e.g. world transform matrix).

A render phase will usually represent drawing onto a new render target. For example, drawing a shadow map for a light will be a phase, and so will drawing the g-buffer.

When a render phase requests items to draw from the scene, the manager for the DrawableComponent entity components will walk through each component, and if it was determined to be visible, it will ask the component can draw for this phase.

If it can, it will submit to the phase a render chunk (piece of geometry to draw), together with a material to use to draw this chunk with this phase, and a (mostly) pre-computed integer key. This key contains stuff like depth and material ID, and is used by the phase to sort each chunk for efficient rendering.

I still haven't decided on what this key is going to be, because exactly how you should order your draw calls can vary a lot depending on your scene (and hardware, but don't think about that too much!). What I'm thinking right now is to have a few bits (2 or 3) for depth, and then everything else by material. This just sticks things into a kind of foreground/background depth buckets and then does mateiral. I might put a more precise depth measurement on the end too, so materials within a bucket go back to sorting by depth.