Board index FlightGear Development Canvas

Canvas documentation

Canvas is FlightGear's new fully scriptable 2D drawing system that will allow you to easily create new instruments, HUDs and even GUI dialogs and custom GUI widgets, without having to write C++ code and without having to rebuild FlightGear.

Canvas documentation

Postby Thorsten » Sat Feb 27, 2016 6:47 am

Hooray wrote in Fri Feb 26, 2016 4:08 pm:In fact, let's face it - you, too, faced quite a steep learning curve when you first tinkered with Canvas despite having an unprecedented track record of working with rendering/graphics code, and all the solid math expertise to understand what a translation is, what a transformation is and what they have in common - and still, we exchanged a bunch of messages to get you going - you stated a few times that the documentation/examples and snippets were lacking, and that you needed to know how to do certain things - and even in this very thread, we're still posting snippets that you are incorporating directly in your code, as we can see in your commits.


This should actually give you pause - if someone who can read Nasal and understands real time rendering and can get up to speed with the C++ rendering code to add tree shadows in a few days can not figure out how to use canvas from the Wiki and the code snippets, then maybe there's a problem with the documentation.

In fact, the missing link is that I have no solid idea what concepts canvas is based on, I'm only gradually developing it by trial and error.

Consider the simple example of making a gauge - I have a rectangle in an SVG mask and want to fill it with a colored bar with its height given by the quantity to display.

What's documented is that I can do

Code: Select all
svg.getElementById("myRectangle");


to get a handle to the element. So what then? What precisely is it I have at the other end of this handle? In the SVG file, there's a gazillion of properties characterizing the rectangle:

Code: Select all
<rect
       style="opacity:1;fill:#00ff00;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
       id="myRectangle"
       width="16.9748"
       height="60.7747"
       x="358.577"
       y="170.425" />


How do they map into what canvas has? I do not know. Is it broken down into four lines? Are the vertex coordinates accessible as an array somewhere? Are width and height accessible? Are the linejoin settings used at all? I do not know.

In fact, the SVG files which I got from Gijs came with both defined clipping regions, and some of them apparently have a slot for animation (aka, their coordinates have an open z-parameter).

Can I use any of this in canvas? If yes, what would be the call to set them? I do not know.

When I load the file, I get an error about 'noneff' not being known. What is a noneff? I do not know.

By patient trial and error, bisecting the SVG and removing properties one by one, I came to understand that the error emerges when the SVG contains a stroke color of 'none' and an opacity of 1, so it would seem canvas tries to string-join hex color and an opacity of ff to get 'none~ff' - which doesn't seem map into a valid coloring request.

Looking into the canvas docs, I can find about accessing SVG:

Code: Select all
# change the background color
myCanvas.set("background", "#ffaac0");

# creating the top-level/root group which will contain all other elements/group
var root = myCanvas.createGroup();

var filename = "/Nasal/canvas/map/Images/boeingAirplane.svg";
var svg_symbol = root.createChild('group');
canvas.parsesvg(svg_symbol, filename);

svg_symbol.setTranslation(width/2,height/2);

#svg_symbol.setScale(0.2);
#svg_symbol.setRotation(radians)


So I can apply translations, rotations and scales - is this all? No, it is not all, because I can also set colors and fill colors. Can I set yet more? I do not know. Can I access the coords of my rectangle directly? I do not know. Can I make use of what seems to be pre-defined motions inside the SVG structure? I do not know.

There's a hidden assumption somewhere that everyone knows these things, that everyone knows what the SVG internally is, what properties it stores and what of that is transferred to canvas when parsing. That everyone is clear on how the group hierarchy works, what properties can be set for whole groups, what are so special that they can't.

I have no trouble finding snippets of this and that on the wiki, quotes copied over from some context which doesn't quite fit, all that. What I can't find is solid documentation. There's no common thread, no big picture, no document outlining the specs.

Yes, I can read api.nas - but I can't figure out easily what an SVG element becomes after I parsed it, aka what section of it applies to my particular use case.

What's missing is like "This is a comprehensive lists of all elements which canvas knows. This is a comprehensive list of properties and methods you can use for element X. This is a list of how SVG elements are mapped into canvas elements. These are the valid ranges for the parameters you can set."

Let me finally quote Durk from the mailing list who seems to echo some of my sentiments:

I've been rather shocked by the current state of affairs on the
flightgear wiki. Somebody seems to think that excessive quoting equates
documentation, but unfortunately makes the wiki close to useless.
Additionally, there are far too many stubs and outdated articles to make
the wikie useful. Wouldn't it be time to initiate a major clean-up?
Thorsten
 
Posts: 11191
Joined: Mon Nov 02, 2009 8:33 am

Re: Canvas documentation

Postby Necolatis » Sat Feb 27, 2016 7:19 am

Did you see this wiki page, made it for just that reason:

http://wiki.flightgear.org/Canvas_Nasal_API
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 2032
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2019.1.2
OS: Windows 10

Re: Canvas documentation

Postby Thorsten » Sat Feb 27, 2016 7:27 am

No, 'cause despite looking eminently useful, it doesn't seem to be in the canvas wiki navigation box and so far nobody has given me the link - I've been told to read api.nas a few times of course.

So what would I have had to do to find it? I do not now.

Edit: Ah, I see it now - it's a bit hidden...
Thorsten
 
Posts: 11191
Joined: Mon Nov 02, 2009 8:33 am

Re: Canvas documentation

Postby Hooray » Sat Feb 27, 2016 12:43 pm

the missing link is that I have no solid idea what concepts canvas is based on


Here's the main concept (found by googling "canvas 2D"): https://en.wikipedia.org/wiki/Canvas_element

In FlightGear, things are a bit different, mainly in that:

  • a Canvas represents an actual OpenGL texture (2D)
  • is hardware-accelerated
  • is using OSG for most of its features
  • there is an actual scenegraph
  • uses Nasal instead of ECMAScript/JavaScript


A FlightGear Canvas is primarily a property tree in the main property tree, where attributes of the texture, and each element, are mapped to "listeners" (or updated via polling).

Internally, this will dispatch events/notifications to the current texture/event.

A Canvas in texture is an invisible offscreen rendering context (RTT/FBO) - it is made visible by adding a so called "placement" to the main FlightGear scenegraph, where the static texture will be replaced with one of the dynamic Canvas textures.

A FlightGear Canvas supports events for UI purposes, so that listeners can be registered for events like "mouseover" etc.

The Canvas scenegraph is a special thing, its root is always a Canvas group - each group can have an arbitrary number of children added, i.e. other elements (or other groups).

The primary Canvas elements are 1) raster images, 2) osgText nodes, 3) map, 4) groups and 5) OpenVG paths.

The FlightGear Canvas system does not understand SVG images - instead, it is using the OpenVG back-end to translate a subset of SVG/XML to Canvas properties by mapping those to OpenVG primitives.

There are many features that are not supported by this SVG parser (svg.nas), but it is written in Nasal and can be easily extended to also support other features, e.g. support for raster images and/or nested SVG images.

Apart from OpenVG, there's no lower level drawing support (think pixels).

So what then? What precisely is it I have at the other end of this handle?


Like I said elsewhere, your problem does not seem to have much to do with understanding graphics or the maths, but with the programming concepts - i.e. you kind of understand everything about thermodynamics, but someone else has taken this knowledge one step further and developed an abstraction of top of that - e.g. combustion engines.

In fact, we seem to many more people without your kind of background, but who still are able to use Canvas/Nasal successfully - i.e. just due to some experience with JavaScript and HTML5/Canvas probably, and maybe some more exposure to OOP ?

Referring to the analogy above, there are people around here who are far from understanding the underlying processes (thermodynamics vs. rendering/graphics), who really just don't possess much more than a driving license, but are quite able to drive said car :D


So, to answer your question: You are getting a Canvas Element, i.e. the child class implementing SVG support, which is the OpenVG (Path) element.

To understand how "paths" work (in the vector image sense), you may want to briefly look up an OpenVG tutorial, because most of that available/applicable to you in FG - like I said, FG/Canvas does not understand SVG images at all, there is a svg.nas module that will parse a subset/part of the SVG spec and turn that into OpenVG (=path) nodes in the FlightGear property tree.

Common functionality resides in the group/element classes, whereas element specific functionality lives inside the corresponding class implementing the feature.

Thus, you don't have access to everything the SVG file specifies - for that, the svg.nas module would need to be extended accordingly - one of the more straightforward changes would be adding support for raster images (e.g. as background images), and/or for embedded/included SVGs.

Likewise, you cannot currently use SVG animations - i.e. they are ignored by the svg.nas parser.

Like I said, I think your real problem may be that the Canvas system, and its wrappers are using OOP, and you haven't yet had much exposure to it, so it may all seem a bit obscure to you, whereas others (with much less exposure to low-level rendering code than you've had), don't seem to struggle with these concepts at all.

I may post more answers later, but my suggestion would be to review the "Canvas" article on wikipedia, and then a short tutorial on "OpenVG".

Next, I would suggest to understand what inheritance in OOP means, i.e. how a child class relates to its parent class (and the functions/fields available there) -once you understand that a SVG image is just a bunch of Canvas Path nodes that are inherited from Canvas element, which are added to a Canvas group, which in turn is added to an OSG texture, you understand that you have a full scenegraph there.

And at that point, you will probably find more of your existing rendering/scenegraph knowledge applicable/useful.

Regarding Durk's comments you "quoted" :lol: on quoting on the wiki, I don't disagree at all - in fact, it would be great if we could do without quotes, but the "Instant Cquotes" article on the wiki explains fairly well, why quotes are useful, i.e. they are a symptom - because people tend to favor long exchanges on the forum/devel list (like this one!) rather than write useful docs in general. In fact, in the spaceshuttle thread, I invited you to help improve the docs by adding to the "Canvas Snippets" article (the clipping example we were discussing). So I don't disagree that quoting is very unfortunate (and ugly), but I think there's too much useful information that would be lost otherwise, especially in the light of most core developers not bothering to document their new features (just look at Phi or the Qt5 launcher). Actually, Canvas is in a fairly good position in comparison.
More recently, I have begun using a different quoting mode/style, that does not look as obnoxious, and I am hoping to refine that: http://wiki.flightgear.org/Graphics_Card_Profiles

To sum it up, most of the people who are really bothered by those quotes are not actively documenting their own features on the wiki at all (I am not referring to you here, I am aware that you have become an avid wiki contributor and that you are documenting your rendering work), it was specifically inspired by Curt and James making postings like those quoted here: http://wiki.flightgear.org/FlightGear_w ... Motivation
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11376
Joined: Tue Mar 25, 2008 8:40 am

Re: Canvas documentation

Postby Thorsten » Sat Feb 27, 2016 3:15 pm

I appreciate the gesture, but you misunderstood the point of my post.

It was to give you insight into thought processes when approaching the documentation which you may (or may not) use to improve it. I've spent a total of four hours with the canvas wiki pages trying to chase down the info I need before giving up and using canvas as cooking recipe. I decided to focus on understanding JSBSim instead which is (for my taste) well documented.

As far as I am concerned and according to my insights now, deleting everything but the code snippets and Necolatis' Nasal API page would improve the canvas wiki significantly as it would much improve the signal to noise ratio.

As I tried to indicate, I have by trial and error worked out the answer to my questions by now.

You generally seem to be of the opinion that it's largely my fault that I don't understand the documentation (because I lack the relevant experience or what not) - so feel free to disregard the feedback. I do however see you point to canvas in multiple threads, and I also see that rarely something comes out of it - so there might be a pointer here as to the why. Or not.

In fact, we seem to many more people without your kind of background, but who still are able to use Canvas/Nasal successfully - i.e. just due to some experience with JavaScript and HTML5/Canvas probably, and maybe some more exposure to OOP ?


You seem to persist in this weird notion that I don't understand or can't code OOP. That was true perhaps three years ago - but if I have decent documentation available I usually go from nothing to operational knowledge in a week, so three years is a long time. And there's very good documentation for C++ available.

I do however not share your notion of when it should be used - I use it when I see value (the worldbuilder code, the DPS hardware management of the Shuttle, the antenna management) and I don't when I don't see value (launch guidance of the Shuttle, stage management,...).

Deliberately not using something however isn't the same as not understanding it.

In fact, in the spaceshuttle thread, I invited you to help improve the docs by adding to the "Canvas Snippets" article


Yes - please leave it to me to document the interfaces to the rendering code I write and don't ask me to document your projects for you. As you may guess from the sheer volume of stuff I am doing for FG, I have no time to help you out. You may find that unfortunate, but that's the reality of it, I can just barely document my own.
Thorsten
 
Posts: 11191
Joined: Mon Nov 02, 2009 8:33 am

Re: Canvas documentation

Postby Necolatis » Wed Aug 16, 2017 11:05 pm

I have updated http://wiki.flightgear.org/Canvas_Nasal_API, with some more methods.
Don't know how I missed those before maybe I was sloppy.

Like how to make rounded rectangle and corrected number of parameters for bezier curves and other details.

Am a bit unsure about which settings can be passed to canvas after init, if any know, please correct the wiki.
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 2032
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2019.1.2
OS: Windows 10

Re: Canvas documentation

Postby Hooray » Thu Aug 17, 2017 8:07 pm

Thanks for doing this - but what exactly is it that you want to know regarding settings that can be passed to canvas "after init" ??
Do you mean stuff that can be set using the .set() API ?
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11376
Joined: Tue Mar 25, 2008 8:40 am

Re: Canvas documentation

Postby Necolatis » Fri Aug 18, 2017 12:19 am

Yes, which of the settings that can be passed to the .set() after initialization.
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 2032
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2019.1.2
OS: Windows 10

Re: Canvas documentation

Postby Hooray » Fri Aug 18, 2017 6:45 pm

There is no simple answer, other than explaining how the whole thing works under the hood:

basically, it's working analogous to the setlistener() API: The Canvas system inherits from SGPropertyChangeListener (PropertyBasedMgr actually) - which is to say that it will be "notified" whenever a property is updated/modified or added - it will look for relevant events, process its own events and pass on all other events to child elements.

In other words, you really only need to look at the childAdded() and valueChanged() methods to see what else can be done.
You will find approximately ~10-20 properties that are explicitly checked there, this is the kind of stuff that can be modified using .set() - and that would also work for most APIs that have a direct API.

Apart from that, all properties that are parsed/processed during each update/rendering step, will obviously be processed without having to go through listeners (i.e. polling).


See for example: https://sourceforge.net/p/flightgear/si ... s.cxx#l521
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11376
Joined: Tue Mar 25, 2008 8:40 am


Return to Canvas

Who is online

Users browsing this forum: No registered users and 1 guest