]> git.mxchange.org Git - simgear.git/commitdiff
canvas::Element: floating point scissor coordinates.
authorThomas Geymayer <tomgey@gmail.com>
Sat, 19 Jul 2014 18:52:17 +0000 (20:52 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Sat, 19 Jul 2014 18:52:17 +0000 (20:52 +0200)
GL_SCISSOR itself only supports integer coordinates, but
with reference frames different from GLOBAL transforms
influence the position of the clipping frame, possibly
resulting in wrong positions due to too low precision.

simgear/canvas/elements/CanvasElement.cxx

index 16b02c26cc77d5e27f45d67c5b5db8df244dec70..5621973491aa66630b2bb0545cf4307a4310b235 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <osg/Drawable>
 #include <osg/Geode>
-#include <osg/Scissor>
+#include <osg/StateAttribute>
 
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/foreach.hpp>
@@ -46,27 +46,34 @@ namespace canvas
    * glScissor with coordinates relative to different reference frames.
    */
   class Element::RelativeScissor:
-    public osg::Scissor
+    public osg::StateAttribute
   {
     public:
 
       ReferenceFrame                _coord_reference;
       osg::observer_ptr<osg::Node>  _node;
 
-      RelativeScissor(osg::Node* node = NULL):
+      explicit RelativeScissor(osg::Node* node = NULL):
         _coord_reference(GLOBAL),
-        _node(node)
+        _node(node),
+        _x(0),
+        _y(0),
+        _width(0),
+        _height(0)
       {
-        _width = 0;
-        _height = 0;
+
       }
 
       /** Copy constructor using CopyOp to manage deep vs shallow copy. */
       RelativeScissor( const RelativeScissor& vp,
                        const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY ):
-        Scissor(vp, copyop),
+        StateAttribute(vp, copyop),
         _coord_reference(vp._coord_reference),
-        _node(vp._node)
+        _node(vp._node),
+        _x(vp._x),
+        _y(vp._y),
+        _width(vp._width),
+        _height(vp._height)
       {}
 
       META_StateAttribute(simgear, RelativeScissor, SCISSOR);
@@ -89,6 +96,24 @@ namespace canvas
         return 0; // passed all the above comparison macros, must be equal.
       }
 
+      virtual bool getModeUsage(StateAttribute::ModeUsage& usage) const
+      {
+        usage.usesMode(GL_SCISSOR_TEST);
+        return true;
+      }
+
+      inline float& x() { return _x; }
+      inline float x() const { return _x; }
+
+      inline float& y() { return _y; }
+      inline float y() const { return _y; }
+
+      inline float& width() { return _width; }
+      inline float width() const { return _width; }
+
+      inline float& height() { return _height; }
+      inline float height() const { return _height; }
+
       virtual void apply(osg::State& state) const
       {
         if( _width <= 0 || _height <= 0 )
@@ -163,6 +188,12 @@ namespace canvas
 
         return false;
       }
+
+    protected:
+      float _x,
+            _y,
+            _width,
+            _height;
   };
 
   //----------------------------------------------------------------------------
@@ -576,10 +607,10 @@ namespace canvas
       _scissor = new RelativeScissor(_transform.get());
 
     // <top>, <right>, <bottom>, <left>
-    _scissor->x() = SGMiscf::roundToInt(values[3]);
-    _scissor->y() = SGMiscf::roundToInt(values[0]);
-    _scissor->width() = SGMiscf::roundToInt(width);
-    _scissor->height() = SGMiscf::roundToInt(height);
+    _scissor->x() = values[3];
+    _scissor->y() = values[0];
+    _scissor->width() = width;
+    _scissor->height() = height;
 
     SGPropertyNode* clip_frame = _node->getChild("clip-frame", 0);
     if( clip_frame )