Howto:Create a 2D drawing API for FlightGear
| IMPORTANT: Some, and possibly most, of the features/ideas discussed here are likely to be affected, and possibly even deprecated, by the ongoing work on providing a property tree-based 2D drawing API accessible from Nasal using the new Canvas system available since FlightGear 2.80 (08/2012). Please see: Canvas for further information
You are advised not to start working on anything directly related to this without first discussing/coordinating your ideas with other FlightGear contributors using the FlightGear developers mailing list or the Canvas forum. Anything related to Canvas Core Development should be discussed first of all with TheTom and Zakalawe. Nasal-space frameworks are being maintained by Philosopher and Hooray currently. talk page..
Come up with the technical requirements and document the exact C++ steps required to make a 2D drawing API accessible to Nasal scripts.
Initial support for the new Canvas 2D rendering API is available in FlightGear 2.8. More recent versions (beyond 2.11+) provide lots enhancements. This article is purely kept for reference here now, as it may help future developers doing similar things.
Creating a new instrument
- make sure that you can build SG+FG from source Howto: Build FlightGear with NetBeans using CMake
- clone the SG/FG repositories FlightGear and Git#Clone and handle Repositories
- create a new topic branch: FlightGear and Git#Local_Branch
- Add a new set of cxx/hxx files to $FG_SRC/Instrumentation/ (e.g. 2D-API.cxx and 2D-API.hxx): to get started quickly, just copy and customize the gyro.* files
- implement the SGSubsystem interface for the new subsystem Howto:Create new subsystems 
- add the new files to the CMake build system: Developing using CMake#Adding_new_files_to_the_build
- add the new subsystem to the instrument_mgr (FGInstrumentMgr::build method)
- implement the interface for the od_gauge instrument
- implement SGPropertyChangeListener to process property tree events and updates 
- add some vector drawing library such as cairo 
- implement a minimum set of 2D primitives
- create a Nasal interface with bindings Howto: Extend Nasal
In 2008, FlightGear core developer Tim Moore wrote this:
$FG_SRC/src/Cockpit/wxradar.cxx and $FG_SRC/src/Cockpit/od_gauge.cxx are the existing examples we have of a custom glass instrument. A more recent addition is available in $FG_SRC/src/Cockpit/NavDisplay.cxx.
The weather radar does work in "FlightGear OSG"; there isn't any weather yet, but it can show other aircraft traffic and is the basis for the ATC radar. $FG_SRC/src/Cockpit/od_gauge.cxx uses the method that would be used for any glass instrument: an osg::Camera that is bound to an off-screen render target, i.e a texture. The texture can then be used anywhere in the scene.
You can integrate arbitrary OpenGL code with an OSG application. It is most friendly to setup and change all OpenGL state using OSG's StateSet mechanism, but even that is not necessary. We use the GUI code from PLIB, which doesn't know anything about OSG. See the SGPuDrawable class for the implementation. The one catch is that OSG has a strong notion of separation between the update of a "scene" and its rendering, and that might not play well with arbitrary existing OpenGL code.
If a vector description of instruments is the way to go, then you should look at using SVG with OpenGL and OSG. The big player here is cairo+glitz, but the last time I looked at this it was hard, perhaps impossible, to coax glitz to draw into an OpenGL context that it had not created. Perhaps this has been solved. Another library is svgl at svgl.sourceforge.net, but I have no idea if it is still alive. Any solution that renders to memory using the CPU is going to be too slow, IMHO.
A moving map is a different beast. It would make sense to implement that as a scene graph in its own right with its own pager. That would require a change in current fg architecture to use a CompositeViewer instead of a single Viewer, but we're contemplating that anyway.