From f6b16e2ba8ebcf4e03346a5929be53f0e0cc4c08 Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Sat, 19 Jul 2014 20:52:17 +0200 Subject: [PATCH] canvas::Element: floating point scissor coordinates. 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 | 55 ++++++++++++++++++----- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/simgear/canvas/elements/CanvasElement.cxx b/simgear/canvas/elements/CanvasElement.cxx index 16b02c26..56219734 100644 --- a/simgear/canvas/elements/CanvasElement.cxx +++ b/simgear/canvas/elements/CanvasElement.cxx @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include @@ -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 _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()); // , , , - _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 )