Canvas view camera element

From FlightGear wiki
Jump to navigation Jump to search
This article is a stub. You can help the wiki by expanding it.
Canvas Camera Views
F-JJTH-SlavedCams-Instrument-09-2017-one.png
Started in 08/2016 (prototyped by F-JJTH)
Description adds support for rendering slave scenery views to a FBO/RTT (texture)
Maintainer(s) none
Contributor(s) none
Status experimental/known issues


Last updated in 09/2017

Status

We have a basic prototype, provided by F-JJTH, who prototyped the whole thing in mid 2016. There are a few issues, and it's using the legacy approach for implementign OD_gauge based avionics, i.e. not yet using the Canvas system.

Gallery

Roadmap

Note  There is a related patch available at https://forum.flightgear.org/viewtopic.php?f=71&t=23929#p317448


  • come up with a new Canvas element inheriting from Canvas::Image 80}% completed
  • add Clement's camera setup routines
  • make the camera render into the texture used by the sub-class

Testing

Once we have a basic prototype working, the new camera element needs to be tested, specifically:

  • using different resolutions
  • displaying multiple/independent camera views
  • all supported Canvas placements
  • shaders and effects
  • ALS
  • Rembrandt
  • Reset/re-init
  • OSG threading modes

Known Issues

C++

The following is the boilerplate code neede to add a new element to the Canvas system inheriting from the Canvas::Image class, i.e. an element having its own allocated Image/texture buffer, which is what we can use to render a camera into it:

diff --git a/simgear/canvas/elements/CMakeLists.txt b/simgear/canvas/elements/CMakeLists.txt
index 2b537c0..4eb1e95 100644
--- a/simgear/canvas/elements/CMakeLists.txt
+++ b/simgear/canvas/elements/CMakeLists.txt
@@ -7,6 +7,7 @@ set(HEADERS
   CanvasMap.hxx
   CanvasPath.hxx
   CanvasText.hxx
+  CanvasView.hxx
 )
 
 set(DETAIL_HEADERS
@@ -20,6 +21,7 @@ set(SOURCES
   CanvasMap.cxx
   CanvasPath.cxx
   CanvasText.cxx
+  CanvasView.cxx
 )
 
 simgear_scene_component(canvas-elements canvas/elements "${SOURCES}" "${HEADERS}")
@@ -28,4 +30,4 @@ simgear_component(canvas-elements/detail canvas/elements/detail "" "${DETAIL_HEA
 add_boost_test(canvas_element
   SOURCES canvas_element_test.cpp
   LIBRARIES ${TEST_LIBS}
-)
\ No newline at end of file
+)
diff --git a/simgear/canvas/elements/CanvasGroup.cxx b/simgear/canvas/elements/CanvasGroup.cxx
index c753c2e..5d2585e 100644
--- a/simgear/canvas/elements/CanvasGroup.cxx
+++ b/simgear/canvas/elements/CanvasGroup.cxx
@@ -23,6 +23,8 @@
 #include "CanvasMap.hxx"
 #include "CanvasPath.hxx"
 #include "CanvasText.hxx"
+#include "CanvasView.hxx"
+
 #include <simgear/canvas/CanvasEventVisitor.hxx>
 #include <simgear/canvas/events/MouseEvent.hxx>
 
@@ -66,6 +68,7 @@ namespace canvas
     add<Map  >(_child_factories);
     add<Path >(_child_factories);
     add<Text >(_child_factories);
+    add<View >(_child_factories);
   }
 
   //----------------------------------------------------------------------------
diff --git a/simgear/canvas/elements/CanvasView.cxx b/simgear/canvas/elements/CanvasView.cxx
new file mode 100644
index 0000000..edae7ab
--- /dev/null
+++ b/simgear/canvas/elements/CanvasView.cxx
@@ -0,0 +1,88 @@
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
+
+#include <simgear_config.h>
+#include "CanvasView.hxx"
+
+#include <cmath>
+
+#include <boost/algorithm/string/predicate.hpp>
+
+namespace simgear
+{
+namespace canvas
+{
+
+  //----------------------------------------------------------------------------
+  const std::string View::TYPE_NAME = "view-camera";
+
+  //----------------------------------------------------------------------------
+  void View::staticInit()
+  {
+    Image::staticInit();
+
+    if( isInit<View>() )
+      return;
+
+    // Do some initialization if needed...
+  }
+
+  //----------------------------------------------------------------------------
+  View::View( const CanvasWeakPtr& canvas,
+            const SGPropertyNode_ptr& node,
+            const Style& parent_style,
+            ElementWeakPtr parent ):
+    Image(canvas, node, parent_style, parent)
+  {
+    staticInit();
+  }
+
+  //----------------------------------------------------------------------------
+  View::~View()
+  {
+
+  }
+
+  //----------------------------------------------------------------------------
+  void View::update(double dt)
+  {
+    Image::update(dt);
+  }
+
+  //----------------------------------------------------------------------------
+  void View::childAdded(SGPropertyNode* parent, SGPropertyNode* child)
+  {
+      return Image::childAdded(parent, child);
+  }
+
+  //----------------------------------------------------------------------------
+  void View::childRemoved(SGPropertyNode* parent, SGPropertyNode* child)
+  {
+      return Image::childRemoved(parent, child);
+  }
+
+  //----------------------------------------------------------------------------
+  void View::valueChanged(SGPropertyNode* child)
+  {
+    return Image::valueChanged(child);
+  }
+
+  //----------------------------------------------------------------------------
+  void View::childChanged(SGPropertyNode* child)
+  {
+      return Image::childChanged(child);
+
+  }
+} // namespace canvas
+} // namespace simgear
diff --git a/simgear/canvas/elements/CanvasView.hxx b/simgear/canvas/elements/CanvasView.hxx
new file mode 100644
index 0000000..7b2ec4e
--- /dev/null
+++ b/simgear/canvas/elements/CanvasView.hxx
@@ -0,0 +1,59 @@
+// Based on https://forum.flightgear.org/viewtopic.php?f=71&t=23929
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
+
+#ifndef CANVAS_VIEW_HXX_
+#define CANVAS_VIEW_HXX_
+
+#include "CanvasImage.hxx"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/unordered_set.hpp>
+
+namespace simgear
+{
+namespace canvas
+{
+  class View:
+    public Image
+  {
+    public:
+      static const std::string TYPE_NAME;
+      static void staticInit();
+
+      View( const CanvasWeakPtr& canvas,
+           const SGPropertyNode_ptr& node,
+           const Style& parent_style,
+           ElementWeakPtr parent = 0 );
+      virtual ~View();
+
+      virtual void update(double dt);
+
+      virtual void childAdded( SGPropertyNode * parent,
+                               SGPropertyNode * child );
+      virtual void childRemoved( SGPropertyNode * parent,
+                                 SGPropertyNode * child );
+      virtual void valueChanged(SGPropertyNode * child);
+
+    //protected:
+
+      virtual void childChanged(SGPropertyNode * child);
+  };
+
+} // namespace canvas
+} // namespace simgear
+
+#endif /* CANVAS_VIEW_HXX_ */

Base Package

Nasal Console

After patching and rebuilding SimGear/FlightGear respectively, and applying the changes to to api.nas in the base package, the following can be pasted into the Nasal Console for testing purposes:

var ELEMENT_NAME ="view-camera"; # to be adapted according to the C++ changes

var myElementTest = {
 ##
 # constructor
 new: func(view=0, width=640,height=480) {
  var m = { parents: [myElementTest] };
  m.dlg = canvas.Window.new([width,height],"dialog");
  m.canvas = m.dlg.createCanvas().setColorBackground(1,1,1,1);
  m.root = m.canvas.createGroup();

  ##
  # instantiate a new element
  me.myElement = m.root.createChild( ELEMENT_NAME );
  me.myElement.set("view-number", view);

  return m;
 }, # new
 
}; # end of myElementTest

var cameras = [
 {view: 0, width : 640, height: 480},
 {view: 1, width : 640, height: 480},
 {view: 2, width : 640, height: 480},
];

foreach(var cam; cameras) {
 var newCam = myElementTest.new( view: cam.view, width: cam.width, height: cam.height );
}

Related

References