Canvas

From FlightGear wiki
Revision as of 17:10, 1 March 2014 by Hooray (talk | contribs)
Jump to navigation Jump to search
Canvas Subsystem
Anniversary4.png
Started in 05/2012 (Available since FlightGear 2.8)
Description Dynamic 2D drawing at runtime using the property tree and scripting (for instruments, HUDs, GUIs)
Maintainer(s) TheTom
Contributor(s) User:TheTom (since 02/2012),
Status Under active development as of 02/2013
Folders

$FG_SRC/Canvas

$SG_SRC/simgear/canvas
Topic branches:
fgdata (main repository, master branch; https://gitorious.org/~tomprogs/fg/toms-fgdata/commits/canvas-gui-demo)
Subforum http://forum.flightgear.org/viewforum.php?f=71


In FlightGear, a Canvas is a dynamically created image (OpenGL texture) that can be created and modified (drawn to) at runtime by using the Property Tree, i.e. via the built-in scripting language Nasal and setting a few properties via setprop() or its OO wrapper props.nas. Canvas textures can be used for a number of different purposes, such as creating fully-scripted avionics (airliner/bizjet -style/MFD glass cockpits) but also custom HUDs and custom GUI textures, even fully interactive GUI widgets (scheduled for FG 4.2+) and interactive scenery elements (e.g. VDGS).

You can use any arbitrary shape to place a canvas onto. For a HUD you just need to create an arbitrarily shaped polygon with your favorite 3d modeling software and place a canvas onto it. As everything drawn onto the canvas goes to an offscreen texture first, only the parts placed onto the 3d model are shown.

You can also draw transparent paths. With the correct blending mode you can just replace all existing contents. It's not named mask, but you can use every canvas element as a mask:

# replace everything already drawn with the pixels of the path
path.set("blend-source", "one")
      .set("blend-destination", "zero");

Currently only rectangular clipping regions are possible (and will be for the next time). You can still get rounded corners if you just draw them in black (or any other background color) on top of the clipped region.

The canvas subsystem is entirely implemented on top of the FlightGear Property Tree, it makes use of property listeners to watch a sub tree of the property tree for canvas-related events (e.g. drawing commands or events to load an image from disk), so that textures can be dynamically instantiated and modified by setting properties in the property tree. This method is not specific to Nasal scripting, the same system can be used by other subsystems (such as the Telnet or HTTP daemons) to create and modify textures without directly using Nasal. The Canvas makes use of OpenVG for 2D rendering.

As of 08/2012, the Canvas system is still under active development and nothing is set in stone yet. See Canvas Properties for further information.

The first prototype of the canvas system became available in FlightGear 2.8, this lacked some features currently under development (notably the Nasal API, support for raster and vector images)- it is expected that a more feature-rich version will be available in the following release, i.e. FlightGear 3.0+ - possibly replacing the entire existing PUI GUI with a fully Canvas-driven implementation in scripting space (one of the primary long-term goals is to modernize the FlightGear GUI).

Future FlightGear versions will contain reimplementations of currently hard-coded instruments such as the wxradar, tcas or navdisplay using the canvas system, so that these can be easily maintained as part of the base package, and so that the same backend code can be also used for creating sophisticated dialogs using the Canvas system, such as ATC displays like ATC-FS, sharing a single backend - without having to re-implement logic for otherwise identical purposes (currently, we have code that implements a navigational display, while another piece of code renders a conceptually identical Map dialog).

Among other advantages, this will also provide for an opportunity to run Canvas-based instruments and GUI elements in another process, or even on another computer, analogous to FGPanel (see FGCanvas).

The canvas system allows you to use SVG images drawn with Inkscape, and easily use raster images and even commpletely custom drawing commands using OpenVG paths.

However, please do note that the canvas cannot currently be run in a standalone/FGPanel-fashion - there's been some talk about that, but that will at least take another 1-2 releases probably. That being said, you could certainly come up with a canvas instrument panel, and then simply use in a dedicated fgfs instance, which is slaved to a corresonding master instance.

Also, there's currently work ongoing to port the old 2D panel and HUD systems to the new Canvas system, using custom Nasal wrappers reimplementing the old behavior and turning the textures into canvas properties.

Requirements and Limitations

Beginning with 2.8, up to 2.99+, all FlightGear versions require FBO support for the canvas system to work properly [1]. In particular, this means that very old GPUs such as Intel 910/915 cards are currently not supported (FBO support is obviously also required for Rembrandt to work).

Unless render-to-texture (RTT) support can be provided through some form of fallback mode for hardware without FBO support, we we might need to consider officially un-supporting such old hardware from 3.0 (since we can already detect the vendor as Intel).

It seems 940-class chips are okay, and the 2000/3000/4000HD versions seem to work, but the earlier 9xx and before are going to be problematic for the time being [2]. At the moment, it isn't clear if telling the od_gauge/OSG backend code to use pbuffer rendering instead of FBOs would already help solve the problem [3].

Latest Canvas Efforts

Using the Canvas in non-FG projects

The canvas system has been refactored such that it can be more easily re-used in other programs, this included moving the Canvas component from FlightGear to SimGear and releasing the canvas code under SimGear's license (LGPL).

It is now possible to use the Canvas in projects unrelated to FlightGear, but you will obviously benefit from using certain FlightGear-related technologies, such as an 1) property tree 2) SGSubsystem-based main loop, 3) an osgviewer-based main window, and 4) Nasal scripting.

Icecode's FGRadar project is such a completely separate code base from FG, which uses SG/FG components to simplify code reuse, without re-inventing the wheel.

For this very purpose, FGRadar uses a custom "SGApplication" framework - so that existing FlightGear subsystems can be more easily reused in different projects. All that's needed is deriving your own class from "SGApplication" and implementing its interface. The whole idea behind "SGApplication" is to provide a scriptable framework for OpenGL applications, fully based on 1) OSG, 2) SGSubsystems, 3) Nasal scripting and 4) the Canvas.

For additional info, see: http://forum.flightgear.org/viewtopic.php?f=71&t=18415

Gallery

Boeing 747-400 PFD and ND approach EHAM 18R.png

A short video demonstrating a possible usecase (C-130J AMU):

By using alphablending it can also be used to render the contents of a HUD:

In my branch there is now also support for using the canvas in a gui widget:

Using the Canvas as a GUI widget

With the new map element it is also very easy to draw maps:

Simple Map of KSFO

Using the new canvas.parsesvg function to use an SVG file to simulate an EICAS display:

Demonstrating how the new Canvas GUI wrapper can be used to create entirely custom, scripted GUI widgets using XML, SVG and Nasal:

Experimenting with selecting text and positioning a cursor inside the text. The visualization is all done using Nasal.

Since 07/2012, the canvas system also provides support for full window-drawing:

Omega95 has reimplemented the CDU of the ATR72 using the Canvas system:

Another video demonstrating window stacking and nested canvases:

Using Canvas mouse events to create animation of slider, wheel and knob