Canvas development: Difference between revisions

Jump to navigation Jump to search
Switch to the {{forum url}} and {{forum link}} templates for all forum links.
(Switch to the {{forum url}} and {{forum link}} templates for all forum links.)
Line 133: Line 133:


The main difference is that certain OSG parameters are exposed in the form of properties, by setting properties using a certain name, type/value, it will call the corresponding OSG machinery to update the texture internally.<ref>{{cite web
The main difference is that certain OSG parameters are exposed in the form of properties, by setting properties using a certain name, type/value, it will call the corresponding OSG machinery to update the texture internally.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=298178#p298178
   |url    =  {{forum url|p=298178}}
   |title  =  <nowiki> Re: Dirty airplanes?? </nowiki>  
   |title  =  <nowiki> Re: Dirty airplanes?? </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 145: Line 145:


Once you stop manipulating a Canvas in the tree (and especially its child elements), it's all native C++ code that is running - i.e. no Nasal or property overhead once the corresponding data structures are set up, but that only holds true until the next "update", at which point everything is removed, re-parsed and updated/re-drawn.<ref>{{cite web
Once you stop manipulating a Canvas in the tree (and especially its child elements), it's all native C++ code that is running - i.e. no Nasal or property overhead once the corresponding data structures are set up, but that only holds true until the next "update", at which point everything is removed, re-parsed and updated/re-drawn.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=298124#p298124
   |url    =  {{forum url|p=298124}}
   |title  =  <nowiki> Re: Dirty airplanes?? </nowiki>  
   |title  =  <nowiki> Re: Dirty airplanes?? </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 167: Line 167:


<ref>{{cite web
<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=298178#p298178
   |url    =  {{forum url|p=298178}}
   |title  =  <nowiki> Re: Dirty airplanes?? </nowiki>  
   |title  =  <nowiki> Re: Dirty airplanes?? </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 222: Line 222:
You will want to add a new Canvas::Element whenever you want to add support for features which cannot be currently expressed easily (or efficiently) using existing means (i.e. via existing elements and scripting space frameworks). For example, this may involve projects requiring camera support, rendering scenery views to a texture, rendering 3D models to a texture or doing a complete moving map with terrain elevations/height maps  (even though the latter could be implemented by sub-classing Canvas::Image to some degree).  
You will want to add a new Canvas::Element whenever you want to add support for features which cannot be currently expressed easily (or efficiently) using existing means (i.e. via existing elements and scripting space frameworks). For example, this may involve projects requiring camera support, rendering scenery views to a texture, rendering 3D models to a texture or doing a complete moving map with terrain elevations/height maps  (even though the latter could be implemented by sub-classing Canvas::Image to some degree).  


Another good example for implementing new elements is rendering file formats like [http://forum.flightgear.org/viewtopic.php?f=71&t=27499&p=258282#p214381 PDF], [[Howto:Extending Canvas to support rendering 3D models|3d models]] or ESRI shape files.
Another good example for implementing new elements is rendering file formats like {{forum link|p=214381|text=PDF}}, [[Howto:Extending Canvas to support rendering 3D models|3d models]] or ESRI shape files.


To add a new element, these are the main steps:
To add a new element, these are the main steps:
Line 511: Line 511:
===AI/MP models ===
===AI/MP models ===
It appears as though it is not possible for Canvas to locate a texture that is in a multiplayer aircraft model; this has also been seen in the efforts to get Canvas displays working on the B777.<ref>{{cite web
It appears as though it is not possible for Canvas to locate a texture that is in a multiplayer aircraft model; this has also been seen in the efforts to get Canvas displays working on the B777.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=279540#p279540
   |url    =  {{forum url|p=279540}}
   |title  =  <nowiki> Re: Dual control for Boeing 777 </nowiki>  
   |title  =  <nowiki> Re: Dual control for Boeing 777 </nowiki>  
   |author =  <nowiki> Hyde </nowiki>  
   |author =  <nowiki> Hyde </nowiki>  
Line 551: Line 551:


actual problem is property I/O - we can't read/write several hundreds of properties per frame without creating a bottleneck. So it's largely irrelevant how fast the Nasal code runs, whether it's parallel or whether it's Python-driven code running on the GPU - as long as property I/O speed doesn't change, performance will be stuck right there.<ref>{{cite web
actual problem is property I/O - we can't read/write several hundreds of properties per frame without creating a bottleneck. So it's largely irrelevant how fast the Nasal code runs, whether it's parallel or whether it's Python-driven code running on the GPU - as long as property I/O speed doesn't change, performance will be stuck right there.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=296410#p296410
   |url    =  {{forum url|p=296410}}
   |title  =  <nowiki> Re: Nasal must go </nowiki>  
   |title  =  <nowiki> Re: Nasal must go </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
Line 560: Line 560:


We're talking 500 properties in addition to everything else that is happening (limit checks, thermal system updates, CWS queries, simulation of co-orbiting objects, simulation of sensor errors,...)<ref>{{cite web
We're talking 500 properties in addition to everything else that is happening (limit checks, thermal system updates, CWS queries, simulation of co-orbiting objects, simulation of sensor errors,...)<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=297665#p297665
   |url    =  {{forum url|p=297665}}
   |title  =  <nowiki> Re: Nasal must go </nowiki>  
   |title  =  <nowiki> Re: Nasal must go </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
Line 572: Line 572:
Now, if these 40, no more than 9 different ones can actually be on at any given time - so that's 450 getprop calls if you do it without data provider.
Now, if these 40, no more than 9 different ones can actually be on at any given time - so that's 450 getprop calls if you do it without data provider.
Now, we're not updating them all at once, we're updating in a staggered fashion - user selectable but per default just one display in a frame - so that's 50 getprop calls per frame. So effectively you get an update rate of ~3 Hz and query only the properties you really need.<ref>{{cite web
Now, we're not updating them all at once, we're updating in a staggered fashion - user selectable but per default just one display in a frame - so that's 50 getprop calls per frame. So effectively you get an update rate of ~3 Hz and query only the properties you really need.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=297596#p297596
   |url    =  {{forum url|p=297596}}
   |title  =  <nowiki> Re: Nasal must go </nowiki>  
   |title  =  <nowiki> Re: Nasal must go </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
Line 583: Line 583:
The workload is certainly a function of the number of screens (canvas textures/FBOs) (unless you can assume have duplicate screens, in which case you can cut it by re-using a canvas or using a data provider).
The workload is certainly a function of the number of screens (canvas textures/FBOs) (unless you can assume have duplicate screens, in which case you can cut it by re-using a canvas or using a data provider).
Creating the property structure by simply copying it turned out to be the largest drag in setting up a canvas display.<ref>{{cite web
Creating the property structure by simply copying it turned out to be the largest drag in setting up a canvas display.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=284756#p284756
   |url    =  {{forum url|p=284756}}
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
Line 591: Line 591:
   }}</ref>
   }}</ref>
if you have a page that displays 90 data values in text, you actually have to fetch all 90 of them. With 9 displays open, that's 810 properties to be fetched and then to be written so that canvas can display them. If you try that per frame, you'll see quickly why it doesn't work.<ref>{{cite web
if you have a page that displays 90 data values in text, you actually have to fetch all 90 of them. With 9 displays open, that's 810 properties to be fetched and then to be written so that canvas can display them. If you try that per frame, you'll see quickly why it doesn't work.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=284756#p284756
   |url    =  {{forum url|p=284756}}
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
Line 599: Line 599:
   }}</ref>
   }}</ref>
Of course there needs to be an information merging and representation stage which the Shuttle doesn't have - but if you put this into the display code itself... see above. Fetching doens of properties when all you need is four pre-computed ones is a bad idea.<ref>{{cite web
Of course there needs to be an information merging and representation stage which the Shuttle doesn't have - but if you put this into the display code itself... see above. Fetching doens of properties when all you need is four pre-computed ones is a bad idea.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=284756#p284756
   |url    =  {{forum url|p=284756}}
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
Line 608: Line 608:


In an extreme case, the shuttle needs to read (and canvas later write) some 800 properties for one screen processing cycle. Part of those trigger unit conversions, mappings to strings,... A small subset goes into translating, rotating and scaling line elements. Our experience is that property reading and writing is usually the most expensive part - with AW Thorsten did not manage even with complex cloud setup calls squeeed into a single frame to make even a dent in the framerate or latency (not for lack of trying), but property access does it as soon as you reach ~1000 per frame.<ref>{{cite web
In an extreme case, the shuttle needs to read (and canvas later write) some 800 properties for one screen processing cycle. Part of those trigger unit conversions, mappings to strings,... A small subset goes into translating, rotating and scaling line elements. Our experience is that property reading and writing is usually the most expensive part - with AW Thorsten did not manage even with complex cloud setup calls squeeed into a single frame to make even a dent in the framerate or latency (not for lack of trying), but property access does it as soon as you reach ~1000 per frame.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=284965#p284965
   |url    =  {{forum url|p=284965}}
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
Line 621: Line 621:
All the polling could be prevented then, and updating would be moved to C++ space.
All the polling could be prevented then, and updating would be moved to C++ space.
We ended up using a similar approach when we noticed that drawing taxiway layers would create remarkable property overhead, so that we troubleshooted the whole thing, at which point, TheTom added helpers to further reduce system/Nasal load<ref>{{cite web
We ended up using a similar approach when we noticed that drawing taxiway layers would create remarkable property overhead, so that we troubleshooted the whole thing, at which point, TheTom added helpers to further reduce system/Nasal load<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=269360#p269360
   |url    =  {{forum url|p=269360}}
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 629: Line 629:
   }}</ref>
   }}</ref>
common coding constructs (such as sprintf/getprop idiom) are put into a helper function, which can later on be re-implemented/optimied, without having to touch tons of files/functions.<ref>{{cite web
common coding constructs (such as sprintf/getprop idiom) are put into a helper function, which can later on be re-implemented/optimied, without having to touch tons of files/functions.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=269353#p269353
   |url    =  {{forum url|p=269353}}
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 637: Line 637:
   }}</ref>
   }}</ref>


In the case of propery-driven labels that are formatted using sprintf(), it would probably be easier to just introduce a helper function, and delegate that to C++ code - as per the comments at: [http://forum.flightgear.org/viewtopic.php?f=71&amp;t=28160 viewtopic.php?f=71&amp;t=28160]<ref>{{cite web
In the case of propery-driven labels that are formatted using sprintf(), it would probably be easier to just introduce a helper function, and delegate that to C++ code - as per the comments at: {{forum link|t=28160}}<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=269332#p269332
   |url    =  {{forum url|p=269332}}
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 646: Line 646:
   }}</ref>
   }}</ref>
It would be better to extend the Canvas system to directly support a new "property mode" using sprintf-style format strings that are assembled/updated in C++ space, i.e. without any Nasal overhead, which would benefit other efforts, too - including the PFD/ND efforts, re-implementing HUD/2D panels on top of Canvas, but even pui2canvas<ref>{{cite web
It would be better to extend the Canvas system to directly support a new "property mode" using sprintf-style format strings that are assembled/updated in C++ space, i.e. without any Nasal overhead, which would benefit other efforts, too - including the PFD/ND efforts, re-implementing HUD/2D panels on top of Canvas, but even pui2canvas<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=266722#p266722
   |url    =  {{forum url|p=266722}}
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 661: Line 661:


<ref>{{cite web
<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=266721#p266721
   |url    =  {{forum url|p=266721}}
   |title  =  <nowiki> Canvas performance (property overhead) (pm/space shuttle) </nowiki>  
   |title  =  <nowiki> Canvas performance (property overhead) (pm/space shuttle) </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 1,147: Line 1,147:


=== Supporting Cameras ===
=== Supporting Cameras ===
{{PatchAvailable|url=https://forum.flightgear.org/viewtopic.php?f=71&t=23929#p317448}}
{{PatchAvailable|url={{forum url|p=317448}}}}


[[File:Fg-multiview-demo.png|right|thumb|OSG slave camera rendered to an TextureRectangle [http://forum.flightgear.org/viewtopic.php?f=6&t=6455&p=260733#p260733]]]
[[File:Fg-multiview-demo.png|right|thumb|OSG slave camera rendered to an TextureRectangle [http://forum.flightgear.org/viewtopic.php?f=6&t=6455&p=260733#p260733]]]
Line 1,713: Line 1,713:


a large benefit for using the raw DEM will be for moving maps - the elevation is pretty much displayable as-is.<ref>{{cite web
a large benefit for using the raw DEM will be for moving maps - the elevation is pretty much displayable as-is.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=294163#p294163
   |url    =  {{forum url|p=294163}}
   |title  =  <nowiki> Re: Next-generation scenery generating? </nowiki>  
   |title  =  <nowiki> Re: Next-generation scenery generating? </nowiki>  
   |author =  <nowiki> psadro_gm </nowiki>  
   |author =  <nowiki> psadro_gm </nowiki>  
Line 2,100: Line 2,100:


Let's assume, we'd like to a new type of placement, one for treating any Canvas as a raster image that can be fetched via the built-in httpd server, or even streamed as a MJPEG.
Let's assume, we'd like to a new type of placement, one for treating any Canvas as a raster image that can be fetched via the built-in httpd server, or even streamed as a MJPEG.
For that to work, we need to be able fetch the Canvas, convert it to an osg::Image and then register the whole thing with the mongoose integration ($FG_SRC/Network/httpd), next we need to register a corresponding camera drawback to obtain the image, and notify the mongoose code to register a new handler and a class providing the corresponding image <ref>https://forum.flightgear.org/viewtopic.php?f=71&t=30642&p=297413#p297413</ref>.
For that to work, we need to be able fetch the Canvas, convert it to an osg::Image and then register the whole thing with the mongoose integration ($FG_SRC/Network/httpd), next we need to register a corresponding camera drawback to obtain the image, and notify the mongoose code to register a new handler and a class providing the corresponding image <ref>{{forum url|p=297413}}</ref>.


In Canvas terms, the way a Canvas is placed is handled by a so called '''Placement''', a placement is just another class that responds to placement-specific events, mainly relevant property updates.
In Canvas terms, the way a Canvas is placed is handled by a so called '''Placement''', a placement is just another class that responds to placement-specific events, mainly relevant property updates.
Line 2,127: Line 2,127:
=== Background ===
=== Background ===
for visualizing orbital mechanics, the two most useful projections are groundtrack (for inclination, node crossing and what you should see looking out of the window) and the projection orthogonal to the orbital plane<ref>{{cite web
for visualizing orbital mechanics, the two most useful projections are groundtrack (for inclination, node crossing and what you should see looking out of the window) and the projection orthogonal to the orbital plane<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=285896#p285896
   |url    =  {{forum url|p=285896}}
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |title  =  <nowiki> Re: Space Shuttle </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
   |author =  <nowiki> Thorsten </nowiki>  
Line 2,173: Line 2,173:
[[File:Map_north_pole_route.jpg|thumb|We've already fixed that in the (old) map dialog, by using an aimuthal equidistant projection. Porting the projection to Canvas is on the todo list. Such a projection is much much better for navigational use.
[[File:Map_north_pole_route.jpg|thumb|We've already fixed that in the (old) map dialog, by using an aimuthal equidistant projection. Porting the projection to Canvas is on the todo list. Such a projection is much much better for navigational use.
Curves in routes are not calculated by Canvas, nor by the ND though. It's the route manager that splits up a route in segments in order to get smooth transitions.<ref>{{cite web
Curves in routes are not calculated by Canvas, nor by the ND though. It's the route manager that splits up a route in segments in order to get smooth transitions.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=227838&sid=91acc3b270c5520b6cc03b34d1b8d011#p227838
   |url    =  {{forum url|p=227838}}
   |title  =  <nowiki> Re: Canvas ND performance issues with route-manager </nowiki>  
   |title  =  <nowiki> Re: Canvas ND performance issues with route-manager </nowiki>  
   |author =  <nowiki> Gijs </nowiki>  
   |author =  <nowiki> Gijs </nowiki>  
Line 2,329: Line 2,329:


there is a dedicated FGCanvasSystemAdapter in $FG_SRC/Canvas that encapsulates the model lookup <ref>{{cite web
there is a dedicated FGCanvasSystemAdapter in $FG_SRC/Canvas that encapsulates the model lookup <ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=285343#p285343
   |url    =  {{forum url|p=285343}}
   |title  =  <nowiki> Re: Dual control for Boeing 777 </nowiki>  
   |title  =  <nowiki> Re: Dual control for Boeing 777 </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 2,345: Line 2,345:
And that should be reflected in the header file
And that should be reflected in the header file
But the implementation would reside in $FG_SRC/Canvas/FGCanvasSystemAdapter.cxx - the SimGear code would only have a copy of the corresponding header file.<ref>{{cite web
But the implementation would reside in $FG_SRC/Canvas/FGCanvasSystemAdapter.cxx - the SimGear code would only have a copy of the corresponding header file.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=317798#p317798
   |url    =  {{forum url|p=317798}}
   |title  =  <nowiki> Re: Gear view in cockpit computer </nowiki>  
   |title  =  <nowiki> Re: Gear view in cockpit computer </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 2,365: Line 2,365:
This would already allow arbitrary views slaved to the main view (camera)  
This would already allow arbitrary views slaved to the main view (camera)  
So as you can see, PagedLOD/CompositeViewer don't need to be involved to make this happen.<ref>{{cite web
So as you can see, PagedLOD/CompositeViewer don't need to be involved to make this happen.<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=261665#p261665
   |url    =  {{forum url|p=261665}}
   |title  =  <nowiki> Re: WINDOW IN WINDOW </nowiki>  
   |title  =  <nowiki> Re: WINDOW IN WINDOW </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
Line 2,374: Line 2,374:


Finally, to use Canvas outside FG, you would also need to look at the FGCanvasSystemAdapter in $FG_SRC/Canvas and provide your own wrapper for your own app (trivial).<ref>{{cite web
Finally, to use Canvas outside FG, you would also need to look at the FGCanvasSystemAdapter in $FG_SRC/Canvas and provide your own wrapper for your own app (trivial).<ref>{{cite web
   |url    =  https://forum.flightgear.org/viewtopic.php?p=237591#p237591
   |url    =  {{forum url|p=237591}}
   |title  =  <nowiki> Re: Simgear-based subsystem with Canvas support? </nowiki>  
   |title  =  <nowiki> Re: Simgear-based subsystem with Canvas support? </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  
   |author =  <nowiki> Hooray </nowiki>  

Navigation menu