Skip to content
Robert Bragg edited this page Jul 13, 2013 · 1 revision

If you are interested in Rig but don't know where to start then hopefully this page of ideas will give you some inspiration. The first couple are good starting points for a newcomer since they offer an easy way to start finding your way around the code base.

Easy starting points

Help update the Internals wiki page

The Internals page aims to explain to newcomers what each file in the Rig code base is for. If you're a newcomer yourself this could also be a good way of finding your feet.

Related to this is the [Tour of the code base](Tour of the code base) page and as you start to learn more about the Rig you may be able to help improve this overview.

Fixing compilation warnings

There's currently quite a lot a noisy compiler warnings when compiling Rig, some of which could even be hiding nasty bugs.

If you follow the README documentation for building Rig then you can look out for "warning:" messages which will refer you to a piece of code that the compiler is suspicious about.

For example this warning:

components/rut-material.c:36:5: warning: initialization from incompatible pointer type
     .setter.object_type = rut_material_set_color_source_asset,
     ^

Points to line 36 in rut/components/rut-material.c and in this case because the property is an asset not an object the code needs to be changed to .setter.asset_type = rut_material_set_color_source_asset,

Since a lot of the warning are likely caused by similar incompatible pointer types one thing to be aware of is RigObject * is often used in the prototype of interface functions that may need to work with objects of many different types. RigObject * is effectively void * which means we don't want the compiler to do static type checks on the arguments to these functions and we will instead rely on runtime type checking.

As an example, considering something like RutButton which would implement the RUT_INTERFACEID_SIZEABLE interface which a get_size function with a prototype like:

void
rut_button_get_size (RutButton *self,
                     float *width,
                     float *height)

Because this function is for implementing the general purpose _SIZEABLE interface though it should use RutObject *self instead because that will avoid a compiler warning in _rut_button_init_type when filling in the RutSizableVTable.

Networking

More fine grained network synchronization

Rig can be connected to a slave device such that UI changes are continuously synchronized with that device as changes are made to get feedback about the real performance. The problem is that whenever the UI changes we simply send the whole UI over the wire instead of sending incremental changes. It would be good if we could make the protocol more fine-grained.

The things of importance here are: rig-slave-master.c/h: A slave master represents the state within the editor for one connection to a slave device. Currently the Rig editor can only be connected to one slave but internally we have considered being able to attach to multiple slaves.

We use protocol buffers and in particular the protobuf-c implementation to serialize and unserialize all UI state, very similar to how we save and load .rig files from disk. This serialization code is in rig-pb.c.

The protocol messages themselves are declared in rig.proto

Because all UI changes anyway need to go through the Undo & Redo journal code in rig-undo-journal.c that's also where we want to drive the network synchronization protocol too. Currently we simply call rig_engine_sync_slaves() within rig_undo_journal_insert() which will result in the full UI being re-sent.

If we could add some new messages to rig.proto that allow for sending incremental updates then in rig_undo_journal_insert we'd be able to first try and synchronize incrementally and only as a fallback send the whole UI.

Profiling

Now that Rig supports connecting to remote devices for testing a design in progress the next step is to support collecting profiling metrics from the device.

We'd like to see the UProf project updated so that it can use protocol buffers instead of dbus for collecting profiling data from a remote source. With that working we can then create visualizations of that data within the Rig editor.

Graphics work

If you're really interested by GPU graphics programming, maybe with some background in games development and OpenGL or D3D then we'd love to have your help adding more interesting effects to Rig and also starting to think of visual ideas that move beyond the photorealistic effects maybe into the realms of generative art or stylized renderers that might give things a cartoon or sketched look for example.

Depending on your experience and creativity there are really so many possibilities here.

In Rig we use the Cogl graphics api which gives us lots of maths utilities, platform portability, portability over OpenGL 1/2/3, OpenGL ES 2/3 and WebGL and due to its state tracking model it's easy to manage orthogonal rendering code for the editor that doesn't conflict with the rendering code of the UI being designed. If you are familiar with GPU concepts from using OpenGL or D3D then you should hopefully not have any difficulty getting to grips with the Cogl api. For a quick example an introduction to the Cogl api please see this tutorial.

If you are more comfortable using OpenGL at this point then we are perfectly happy to see ideas developed first in OpenGL and we can figure adapting it to Cogl afterwards since that's likely to be the easy bit anyway.

Experimenting with new renderer ideas

The bulk of all rendering code lives in rig-renderer.c currently because we only have one general purpose renderer supporting photorealism. The intention is to have a renderer interface that lets up implement multiple renderers that can be switched at runtime. A renderer is responsible for taking a graph of entities each with a particular set of components associated with various properties and the renderer should traverse the graph to draw something.

There are really very few constraints imposed on the renderer as to how it can draw things and a renderer is free to ignore whatever entities it doesn't understand or care about and similarly for components and properties.