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.
This commit is contained in:
parent
e415b08da4
commit
f6b16e2ba8
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include <osg/Drawable>
|
#include <osg/Drawable>
|
||||||
#include <osg/Geode>
|
#include <osg/Geode>
|
||||||
#include <osg/Scissor>
|
#include <osg/StateAttribute>
|
||||||
|
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
@ -46,27 +46,34 @@ namespace canvas
|
|||||||
* glScissor with coordinates relative to different reference frames.
|
* glScissor with coordinates relative to different reference frames.
|
||||||
*/
|
*/
|
||||||
class Element::RelativeScissor:
|
class Element::RelativeScissor:
|
||||||
public osg::Scissor
|
public osg::StateAttribute
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ReferenceFrame _coord_reference;
|
ReferenceFrame _coord_reference;
|
||||||
osg::observer_ptr<osg::Node> _node;
|
osg::observer_ptr<osg::Node> _node;
|
||||||
|
|
||||||
RelativeScissor(osg::Node* node = NULL):
|
explicit RelativeScissor(osg::Node* node = NULL):
|
||||||
_coord_reference(GLOBAL),
|
_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. */
|
/** Copy constructor using CopyOp to manage deep vs shallow copy. */
|
||||||
RelativeScissor( const RelativeScissor& vp,
|
RelativeScissor( const RelativeScissor& vp,
|
||||||
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY ):
|
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY ):
|
||||||
Scissor(vp, copyop),
|
StateAttribute(vp, copyop),
|
||||||
_coord_reference(vp._coord_reference),
|
_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);
|
META_StateAttribute(simgear, RelativeScissor, SCISSOR);
|
||||||
@ -89,6 +96,24 @@ namespace canvas
|
|||||||
return 0; // passed all the above comparison macros, must be equal.
|
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
|
virtual void apply(osg::State& state) const
|
||||||
{
|
{
|
||||||
if( _width <= 0 || _height <= 0 )
|
if( _width <= 0 || _height <= 0 )
|
||||||
@ -163,6 +188,12 @@ namespace canvas
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
float _x,
|
||||||
|
_y,
|
||||||
|
_width,
|
||||||
|
_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -576,10 +607,10 @@ namespace canvas
|
|||||||
_scissor = new RelativeScissor(_transform.get());
|
_scissor = new RelativeScissor(_transform.get());
|
||||||
|
|
||||||
// <top>, <right>, <bottom>, <left>
|
// <top>, <right>, <bottom>, <left>
|
||||||
_scissor->x() = SGMiscf::roundToInt(values[3]);
|
_scissor->x() = values[3];
|
||||||
_scissor->y() = SGMiscf::roundToInt(values[0]);
|
_scissor->y() = values[0];
|
||||||
_scissor->width() = SGMiscf::roundToInt(width);
|
_scissor->width() = width;
|
||||||
_scissor->height() = SGMiscf::roundToInt(height);
|
_scissor->height() = height;
|
||||||
|
|
||||||
SGPropertyNode* clip_frame = _node->getChild("clip-frame", 0);
|
SGPropertyNode* clip_frame = _node->getChild("clip-frame", 0);
|
||||||
if( clip_frame )
|
if( clip_frame )
|
||||||
|
Loading…
Reference in New Issue
Block a user