Phobos

In greek mythology, Phobos is Deimos' twin brother. In Vishwakarma, we like to think of Phobos as Deimos older brother that has all the fun and has his little brother do all the dirty work.

While Deimos contains the core API and is quite sufficient for the construction of say, a media player application, Phobos provides extensions that support the development of interactive editing software. It provides the DemoManager class, which aggregates the EffectManager and extends it with features such as XML I/O and a higher-level, semantically aware interface towards the Effects.

In contrast with Deimos, Phobos is aware of the types of Effect's parameters, inputs and outputs. It uses the afore mentioned XML files that describe the effect to ensure than incompatible effects are not connected, and that parameter values are confined to ranges accepted by the effects. It is also aware of something we call “semantic types”, which is information about how parameters should be interpreted. For instance, an effect can specify (in the XML description) that its parameter “color”, which is an integer, has the semantic type “ColorRGBA”. Multiple “physical types” such as integers and floats can map to the same semantic type. This semantic type can be queried by the editing software so that it can take appropriate action, such as presenting the user with a color chooser dialog instead of using a text box and expecting the user to type a decimal value between 0 and 16777215. Below is an example of an effect whose parameters all have explicit semantic types. It shows how parameter value ranges are specified both for simple types and more complex types such as Vector2.

<Effect id ="6" name="Text" maxInputs="1" outputType="RGBAImage">

 3:         <Input>
 5:             <InputType name="RGBAImage"/>
 7:         </Input>
 9:         <Parameter name="Text" type="String" default="amc"/>
11:         <Parameter name="Font" type="String" default="Arial"/>
13:         <Parameter name="Size" type="Short" default="16">
15:             <Range start="1" end="600"/>
17:             <Semantic type="Size"/>
19:         </Parameter>
21:         <Parameter name="Weight" type="Short" default="0">
23:             <Range start="0" end="1000"/>
25:             <Semantic type="Size"/>
27:         </Parameter>
29:         <Parameter name="Color" type="uInteger" default="0xff00ff">
31:             <Range start="0" end="16777215"/>
33:             <Semantic type="ColorRGBA"/>
35:         </Parameter>
37:         <Parameter name="Position" type="Vector2" default="0,0">
39:             <Range component="x" start="-512" end="512"/>
41:             <Range component="y" start="-512" end="512"/>
43:             <Semantic type="PositionXY"/>
45:         </Parameter>
47:     </Effect>



Sine the output types of Operators are completely arbitrary, and only known by the effects themselves (The system sees only void pointers) Phobos has no way of knowing how to render a graphical representation of an effect's output. This is why we have Effect Renderers.

Effect Renders

Effect Renderers are plugins which can handle rendering of one or more output types and optionally the rendering of specific effects. They can be registered with the DemoManager. When the DemoManager's renderEffectOutput(uShort effectID) function it is called, the Demo Manager retrieves the Effect Data structure for the effect with number “effectID”, and checks its output type. Then it goes through the list of available Effect Renderers, and checks if one of them supports the desired output type. If there is one that matches both the effect name and the output type, it is chosen. If not, the first one which supports the output type is chosen.

You might be wondering why effect renderers should be able to support rendering of individual effects, rather than only the output types. “An image is an image is an image”, you might say. Let's take the example of a renderer for effects with output type “Mesh”. It will work very well with standard mesh Effects such as “make sphere”, “twist”, “transform” or “subdivide”. However, imagine a “Selection Cube” effect. It takes an input mesh, and its parameters describe the position and size of an axis-aligned cube, and will produce an output Mesh which has all the vertices that are contained within the cube marked as “selected”. Any further mesh operations will only operate on those vertices that are selected. This is all very well, but the problem is that the standard mesh effect renderer will have little to offer in terms of visual feedback. It will render the mesh, possibly highlighting the selected polygons. This is hardly intuitive, and the user would probably like to be able to see the selection cube rendered in i wireframe as he/she is modifying the size and position of the cube. This is where the specialized “Selection Cube” Effect Renderer comes in. It will override the generic Mesh Effect Renderer, and provide the rendering of the wireframe cube. There are other examples where generic effect renderers simply, won't cut it. However, for the majority of effects, they will do just fine.

Another feature of Effect Renderers is that they implement keyboard and mouse handling. A Mesh Effect Renderer effect can make the render window act as a virtual trackball, the specialized “draw text” render might allow the user to use the mouse to place the text and the keyboard to enter it etc.

The definition of the EffectRenderer class is as follows:

class EffectRenderer {

        public:
                virtual void renderEffect(Effect *effect, Float time, Rect &bounds)=0;
                virtual void mouseClicked(MouseData &args);
                virtual void mouseMoved(MouseData &args);
                virtual void mousePressed(MouseData &args);
                virtual void mouseReleased(MouseData &args);
                virtual void mouseDoubleClicked(MouseData &args);
                virtual void mouseDragged(MouseData &args);
                virtual void mouseEntered(MouseData &args);
                virtual void mouseLeaved(MouseData &args);
                virtual void keyboardPressed(KeyboardData &args);
                virtual void keyboardReleased(KeyboardData &args);
                virtual void keyboardReturnPressed(KeyboardData &args);
                Bool supports(EffectDataType &type);
};

The definition of the EffectRenderer class is as follows: