Allow filling paths and do some clean up/fixing.
This commit is contained in:
parent
c8e1433a5c
commit
569042acbd
11 changed files with 159 additions and 129 deletions
|
@ -1,12 +1,14 @@
|
|||
#SET(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib")
|
||||
include(CheckIncludeFile)
|
||||
check_include_file("inttypes.h" HAVE_INTTYPES_H)
|
||||
|
||||
ADD_DEFINITIONS(
|
||||
-DVG_API_EXPORT
|
||||
-DHAVE_INTTYPES_H
|
||||
)
|
||||
if(HAVE_INTTYPES_H)
|
||||
add_definitions(-DHAVE_INTTYPES_H)
|
||||
endif()
|
||||
add_definitions(-DVG_API_EXPORT)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
../include
|
||||
)
|
||||
|
||||
SET(INCROOT ../include/VG)
|
||||
|
@ -44,10 +46,3 @@ TARGET_LINK_LIBRARIES(
|
|||
${OPENGL_gl_LIBRARY}
|
||||
${OPENGL_glu_LIBRARY}
|
||||
)
|
||||
|
||||
#INSTALL(
|
||||
# TARGETS OpenVG
|
||||
# RUNTIME DESTINATION bin COMPONENT bin
|
||||
# LIBRARY DESTINATION lib${LIB_SUFFIX} COMPONENT bin
|
||||
# ARCHIVE DESTINATION lin${LIB_SUFFIX} COMPONENT devel
|
||||
#)
|
||||
|
|
|
@ -317,21 +317,23 @@ VGU_API_CALL VGUErrorCode vguComputeWarpQuadToSquare(VGfloat sx0, VGfloat sy0,
|
|||
VGfloat *matrix)
|
||||
{
|
||||
/* Basic idea taken from the reference implementation */
|
||||
VGfloat mat[3][3];
|
||||
VGfloat det, det00, det01, det02;
|
||||
|
||||
if( !matrix )
|
||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
||||
VGfloat mat[3][3];
|
||||
if( vguComputeWarpSquareToQuad( sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3,
|
||||
(VGfloat*)mat )
|
||||
== VGU_BAD_WARP_ERROR )
|
||||
return VGU_BAD_WARP_ERROR;
|
||||
|
||||
// Invert the matrix...
|
||||
VGfloat det00 = mat[1][1]*mat[2][2] - mat[2][1]*mat[1][2];
|
||||
VGfloat det01 = mat[2][0]*mat[1][2] - mat[1][0]*mat[2][2];
|
||||
VGfloat det02 = mat[1][0]*mat[2][1] - mat[2][0]*mat[1][1];
|
||||
det00 = mat[1][1]*mat[2][2] - mat[2][1]*mat[1][2];
|
||||
det01 = mat[2][0]*mat[1][2] - mat[1][0]*mat[2][2];
|
||||
det02 = mat[1][0]*mat[2][1] - mat[2][0]*mat[1][1];
|
||||
|
||||
VGfloat det = mat[0][0]*det00 + mat[0][1]*det01 + mat[0][2]*det02;
|
||||
det = mat[0][0]*det00 + mat[0][1]*det01 + mat[0][2]*det02;
|
||||
if( det == 0.0f )
|
||||
return VGU_BAD_WARP_ERROR;
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@ void Canvas::reset(SGPropertyNode* node)
|
|||
|
||||
if( _node )
|
||||
{
|
||||
_root_group.reset( new canvas::Group(_node) );
|
||||
_node->tie
|
||||
(
|
||||
"size[0]",
|
||||
|
@ -198,9 +199,7 @@ void Canvas::update(double delta_time_sec)
|
|||
_texture.useStencil(true);
|
||||
_texture.allocRT(_camera_callback);
|
||||
_texture.getCamera()->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f , 1.0f));
|
||||
|
||||
for( size_t i = 0; i < _groups.size(); ++i )
|
||||
_texture.getCamera()->addChild( _groups[i]->getMatrixTransform() );
|
||||
_texture.getCamera()->addChild(_root_group->getMatrixTransform());
|
||||
|
||||
if( _texture.serviceable() )
|
||||
{
|
||||
|
@ -213,8 +212,7 @@ void Canvas::update(double delta_time_sec)
|
|||
}
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < _groups.size(); ++i )
|
||||
_groups[i]->update(delta_time_sec);
|
||||
_root_group->update(delta_time_sec);
|
||||
|
||||
if( _sampling_dirty )
|
||||
{
|
||||
|
@ -351,19 +349,11 @@ void Canvas::childAdded( SGPropertyNode * parent,
|
|||
if( parent != _node )
|
||||
return;
|
||||
|
||||
if( child->getNameString() == "group" )
|
||||
{
|
||||
_groups.push_back
|
||||
(
|
||||
boost::shared_ptr<canvas::Group>(new canvas::Group(child))
|
||||
);
|
||||
if( _texture.serviceable() )
|
||||
_texture.getCamera()->addChild( _groups.back()->getMatrixTransform() );
|
||||
}
|
||||
else if( child->getNameString() == "placement" )
|
||||
{
|
||||
if( child->getNameString() == "placement" )
|
||||
_dirty_placements.push_back(child);
|
||||
}
|
||||
else
|
||||
static_cast<canvas::Element*>(_root_group.get())
|
||||
->childAdded(parent, child);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -375,10 +365,13 @@ void Canvas::childRemoved( SGPropertyNode * parent,
|
|||
|
||||
if( child->getNameString() == "placement" )
|
||||
clearPlacements(child->getIndex());
|
||||
else
|
||||
static_cast<canvas::Element*>(_root_group.get())
|
||||
->childRemoved(parent, child);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Canvas::valueChanged(SGPropertyNode * node)
|
||||
void Canvas::valueChanged(SGPropertyNode* node)
|
||||
{
|
||||
if( node->getParent()->getParent() == _node )
|
||||
{
|
||||
|
@ -406,6 +399,8 @@ void Canvas::valueChanged(SGPropertyNode * node)
|
|||
|| node->getNameString() == "color-samples" )
|
||||
_sampling_dirty = true;
|
||||
}
|
||||
|
||||
_root_group->valueChanged(node);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <simgear/props/props.hxx>
|
||||
#include <osg/NodeCallback>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace canvas
|
||||
|
@ -88,6 +88,7 @@ class Canvas:
|
|||
_color_dirty;
|
||||
|
||||
FGODGauge _texture;
|
||||
std::auto_ptr<canvas::Group> _root_group;
|
||||
|
||||
SGPropertyNode_ptr _node;
|
||||
std::vector<SGPropertyNode_ptr> _color_background;
|
||||
|
@ -97,9 +98,6 @@ class Canvas:
|
|||
std::vector<SGPropertyNode*> _dirty_placements;
|
||||
std::vector<Placements> _placements;
|
||||
|
||||
// TODO replace auto_ptr with unique_ptr as soon as C++11 is used!
|
||||
std::vector<boost::shared_ptr<canvas::Group> > _groups;
|
||||
|
||||
void setStatusFlags(unsigned int flags, bool set = true);
|
||||
void clearPlacements(int index);
|
||||
void clearPlacements();
|
||||
|
|
|
@ -126,53 +126,6 @@ namespace canvas
|
|||
return _transform;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Element::Element(SGPropertyNode_ptr node, uint32_t attributes_used):
|
||||
_attributes_used( attributes_used ),
|
||||
_attributes_dirty( attributes_used ),
|
||||
_transform_dirty( false ),
|
||||
_transform( new osg::MatrixTransform ),
|
||||
_node( node ),
|
||||
_drawable( 0 )
|
||||
{
|
||||
assert( _node );
|
||||
_node->addChangeListener(this);
|
||||
|
||||
if( _attributes_used & COLOR )
|
||||
linkColorNodes("color", _node, _color, osg::Vec4f(0,1,0,1));
|
||||
|
||||
if( _attributes_used & COLOR_FILL )
|
||||
linkColorNodes("color-fill", _node, _color_fill);
|
||||
|
||||
SG_LOG
|
||||
(
|
||||
SG_GL,
|
||||
SG_DEBUG,
|
||||
"New canvas element " << node->getPath()
|
||||
);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Element::setDrawable( osg::Drawable* drawable )
|
||||
{
|
||||
_drawable = drawable;
|
||||
assert( _drawable );
|
||||
|
||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||
geode->addDrawable(_drawable);
|
||||
_transform->addChild(geode);
|
||||
|
||||
if( _attributes_used & BOUNDING_BOX )
|
||||
{
|
||||
SGPropertyNode* bb_node = _node->getChild("bounding-box", 0, true);
|
||||
_bounding_box.resize(4);
|
||||
_bounding_box[0] = bb_node->getChild("min-x", 0, true);
|
||||
_bounding_box[1] = bb_node->getChild("min-y", 0, true);
|
||||
_bounding_box[2] = bb_node->getChild("max-x", 0, true);
|
||||
_bounding_box[3] = bb_node->getChild("max-y", 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Element::childAdded(SGPropertyNode* parent, SGPropertyNode* child)
|
||||
{
|
||||
|
@ -261,4 +214,51 @@ namespace canvas
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Element::Element(SGPropertyNode_ptr node, uint32_t attributes_used):
|
||||
_attributes_used( attributes_used ),
|
||||
_attributes_dirty( attributes_used ),
|
||||
_transform_dirty( false ),
|
||||
_transform( new osg::MatrixTransform ),
|
||||
_node( node ),
|
||||
_drawable( 0 )
|
||||
{
|
||||
assert( _node );
|
||||
_node->addChangeListener(this);
|
||||
|
||||
if( _attributes_used & COLOR )
|
||||
linkColorNodes("color", _node, _color, osg::Vec4f(0,1,0,1));
|
||||
|
||||
if( _attributes_used & COLOR_FILL )
|
||||
linkColorNodes("color-fill", _node, _color_fill, osg::Vec4f(1,0,1,1));
|
||||
|
||||
SG_LOG
|
||||
(
|
||||
SG_GL,
|
||||
SG_DEBUG,
|
||||
"New canvas element " << node->getPath()
|
||||
);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Element::setDrawable( osg::Drawable* drawable )
|
||||
{
|
||||
_drawable = drawable;
|
||||
assert( _drawable );
|
||||
|
||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||
geode->addDrawable(_drawable);
|
||||
_transform->addChild(geode);
|
||||
|
||||
if( _attributes_used & BOUNDING_BOX )
|
||||
{
|
||||
SGPropertyNode* bb_node = _node->getChild("bounding-box", 0, true);
|
||||
_bounding_box.resize(4);
|
||||
_bounding_box[0] = bb_node->getChild("min-x", 0, true);
|
||||
_bounding_box[1] = bb_node->getChild("min-y", 0, true);
|
||||
_bounding_box[2] = bb_node->getChild("max-x", 0, true);
|
||||
_bounding_box[3] = bb_node->getChild("max-y", 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace canvas
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace canvas
|
|||
{
|
||||
|
||||
class Element:
|
||||
private SGPropertyChangeListener
|
||||
public SGPropertyChangeListener
|
||||
{
|
||||
public:
|
||||
virtual ~Element() = 0;
|
||||
|
@ -46,6 +46,12 @@ namespace canvas
|
|||
|
||||
osg::ref_ptr<osg::MatrixTransform> getMatrixTransform();
|
||||
|
||||
virtual void childAdded( SGPropertyNode * parent,
|
||||
SGPropertyNode * child );
|
||||
virtual void childRemoved( SGPropertyNode * parent,
|
||||
SGPropertyNode * child );
|
||||
virtual void valueChanged(SGPropertyNode * child);
|
||||
|
||||
protected:
|
||||
|
||||
enum Attributes
|
||||
|
@ -93,12 +99,6 @@ namespace canvas
|
|||
osg::Drawable *_drawable;
|
||||
|
||||
Element(const Element&);// = delete
|
||||
|
||||
virtual void childAdded( SGPropertyNode * parent,
|
||||
SGPropertyNode * child );
|
||||
virtual void childRemoved( SGPropertyNode * parent,
|
||||
SGPropertyNode * child );
|
||||
virtual void valueChanged(SGPropertyNode * child);
|
||||
};
|
||||
|
||||
} // namespace canvas
|
||||
|
|
|
@ -58,13 +58,6 @@ namespace canvas
|
|||
element.reset( new Group(child) );
|
||||
else if( child->getNameString() == "path" )
|
||||
element.reset( new Path(child) );
|
||||
else
|
||||
SG_LOG
|
||||
(
|
||||
SG_GL,
|
||||
SG_WARN,
|
||||
"canvas::Group unknown child: " << child->getDisplayName()
|
||||
);
|
||||
|
||||
if( !element )
|
||||
return;
|
||||
|
|
|
@ -38,16 +38,13 @@ namespace canvas
|
|||
PathDrawable():
|
||||
_path(VG_INVALID_HANDLE),
|
||||
_paint(VG_INVALID_HANDLE),
|
||||
_attributes_dirty(~0),
|
||||
_stroke_width(1)
|
||||
_paint_fill(VG_INVALID_HANDLE),
|
||||
_attributes_dirty(~0),
|
||||
_stroke_width(1),
|
||||
_fill(false)
|
||||
{
|
||||
setSupportsDisplayList(false);
|
||||
setDataVariance(Object::DYNAMIC);
|
||||
|
||||
_paint_color[0] = 0;
|
||||
_paint_color[1] = 1;
|
||||
_paint_color[2] = 1;
|
||||
_paint_color[3] = 1;
|
||||
}
|
||||
|
||||
virtual ~PathDrawable()
|
||||
|
@ -92,8 +89,26 @@ namespace canvas
|
|||
void setColor(const osg::Vec4& color)
|
||||
{
|
||||
for( size_t i = 0; i < 4; ++i )
|
||||
_paint_color[i] = color[i];
|
||||
_attributes_dirty |= PAINT_COLOR;
|
||||
_stroke_color[i] = color[i];
|
||||
_attributes_dirty |= STROKE_COLOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable filling of the path
|
||||
*/
|
||||
void enableFill(bool enable)
|
||||
{
|
||||
_fill = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the line color
|
||||
*/
|
||||
void setColorFill(const osg::Vec4& color)
|
||||
{
|
||||
for( size_t i = 0; i < 4; ++i )
|
||||
_fill_color[i] = color[i];
|
||||
_attributes_dirty |= FILL_COLOR;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,18 +161,13 @@ namespace canvas
|
|||
}
|
||||
|
||||
// Initialize/Update the paint
|
||||
if( _attributes_dirty & (PAINT_COLOR | STROKE) )
|
||||
if( _attributes_dirty & (STROKE_COLOR | STROKE) )
|
||||
{
|
||||
if( _paint == VG_INVALID_HANDLE )
|
||||
{
|
||||
_paint = vgCreatePaint();
|
||||
vgSetPaint(_paint, VG_STROKE_PATH);
|
||||
}
|
||||
|
||||
if( _attributes_dirty & PAINT_COLOR )
|
||||
{
|
||||
vgSetParameterfv(_paint, VG_PAINT_COLOR, 4, _paint_color);
|
||||
}
|
||||
if( _attributes_dirty & STROKE_COLOR )
|
||||
vgSetParameterfv(_paint, VG_PAINT_COLOR, 4, _stroke_color);
|
||||
if( _attributes_dirty & STROKE )
|
||||
{
|
||||
vgSetf(VG_STROKE_LINE_WIDTH, _stroke_width);
|
||||
|
@ -167,15 +177,41 @@ namespace canvas
|
|||
_stroke_dash.empty() ? 0 : &_stroke_dash[0] );
|
||||
}
|
||||
|
||||
_attributes_dirty &= ~(PAINT_COLOR | STROKE);
|
||||
_attributes_dirty &= ~(STROKE_COLOR | STROKE);
|
||||
}
|
||||
|
||||
// Initialize/update fill paint
|
||||
if( _attributes_dirty & (FILL_COLOR | FILL) )
|
||||
{
|
||||
if( _paint_fill == VG_INVALID_HANDLE )
|
||||
_paint_fill = vgCreatePaint();
|
||||
|
||||
if( _attributes_dirty & FILL_COLOR )
|
||||
vgSetParameterfv(_paint_fill, VG_PAINT_COLOR, 4, _fill_color);
|
||||
|
||||
_attributes_dirty &= ~(FILL_COLOR | FILL);
|
||||
}
|
||||
|
||||
// Detect draw mode
|
||||
VGbitfield mode = 0;
|
||||
if( _stroke_width > 0 )
|
||||
{
|
||||
mode |= VG_STROKE_PATH;
|
||||
vgSetPaint(_paint, VG_STROKE_PATH);
|
||||
}
|
||||
if( _fill )
|
||||
{
|
||||
mode |= VG_FILL_PATH;
|
||||
vgSetPaint(_paint_fill, VG_FILL_PATH);
|
||||
}
|
||||
|
||||
// And finally draw the path
|
||||
vgDrawPath(_path, VG_STROKE_PATH);
|
||||
if( mode )
|
||||
vgDrawPath(_path, mode);
|
||||
|
||||
VGErrorCode err = vgGetError();
|
||||
if( err != VG_NO_ERROR )
|
||||
std::cout << "vgError: " << err << std::endl;
|
||||
SG_LOG(SG_GL, SG_ALERT, "vgError: " << err);
|
||||
|
||||
glPopAttrib();
|
||||
glPopClientAttrib();
|
||||
|
@ -188,27 +224,33 @@ namespace canvas
|
|||
enum Attributes
|
||||
{
|
||||
PATH = 0x0001,
|
||||
PAINT_COLOR = 0x0002,
|
||||
STROKE = 0x0004
|
||||
STROKE_COLOR = PATH << 1,
|
||||
STROKE = STROKE_COLOR << 1,
|
||||
FILL_COLOR = STROKE << 1,
|
||||
FILL = FILL_COLOR << 1
|
||||
};
|
||||
|
||||
mutable VGPath _path;
|
||||
mutable VGPaint _paint;
|
||||
mutable VGPaint _paint_fill;
|
||||
mutable uint32_t _attributes_dirty;
|
||||
|
||||
CmdList _cmds;
|
||||
CoordList _coords;
|
||||
|
||||
VGfloat _paint_color[4];
|
||||
VGfloat _stroke_color[4];
|
||||
VGfloat _stroke_width;
|
||||
std::vector<VGfloat> _stroke_dash;
|
||||
|
||||
bool _fill;
|
||||
VGfloat _fill_color[4];
|
||||
};
|
||||
|
||||
bool PathDrawable::_vg_initialized = false;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Path::Path(SGPropertyNode_ptr node):
|
||||
Element(node, COLOR /*| COLOR_FILL*/), // TODO fill color
|
||||
Element(node, COLOR | COLOR_FILL),
|
||||
_path( new PathDrawable() )
|
||||
{
|
||||
setDrawable(_path);
|
||||
|
@ -257,6 +299,8 @@ namespace canvas
|
|||
else if( child->getNameString() == "stroke-width"
|
||||
|| child->getNameString() == "stroke-dasharray" )
|
||||
_attributes_dirty |= STROKE;
|
||||
else if( child->getNameString() == "fill" )
|
||||
_path->enableFill( child->getBoolValue() );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -268,7 +312,7 @@ namespace canvas
|
|||
//----------------------------------------------------------------------------
|
||||
void Path::colorFillChanged(const osg::Vec4& color)
|
||||
{
|
||||
|
||||
_path->setColorFill(color);
|
||||
}
|
||||
|
||||
} // namespace canvas
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace canvas
|
|||
void linkColorNodes( const char* name,
|
||||
SGPropertyNode* parent,
|
||||
std::vector<SGPropertyNode_ptr>& nodes,
|
||||
const osg::Vec4& def = osg::Vec4(0,0,0,0) );
|
||||
const osg::Vec4& def = osg::Vec4(0,0,0,1) );
|
||||
|
||||
} // namespace canvas
|
||||
|
||||
|
|
|
@ -64,6 +64,9 @@ if(ENABLE_JSBSIM)
|
|||
target_link_libraries(fgfs JSBSim)
|
||||
endif()
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src/Canvas/ShivaVG/include)
|
||||
add_definitions(-DVG_API_EXPORT)
|
||||
|
||||
target_link_libraries(fgfs
|
||||
${SIMGEAR_LIBRARIES}
|
||||
${OPENSCENEGRAPH_LIBRARIES}
|
||||
|
|
Loading…
Add table
Reference in a new issue