elements/text.hxx
property_helper.hxx
)
-
+
flightgear_component(Canvas "${SOURCES}" "${HEADERS}")
add_subdirectory(ShivaVG/src)
\ No newline at end of file
-#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)
ShivaVG
${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
-#)
+)
\ No newline at end of file
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;
if( _node )
{
+ _root_group.reset( new canvas::Group(_node) );
_node->tie
(
"size[0]",
_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() )
{
}
}
- for( size_t i = 0; i < _groups.size(); ++i )
- _groups[i]->update(delta_time_sec);
+ _root_group->update(delta_time_sec);
if( _sampling_dirty )
{
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);
}
//------------------------------------------------------------------------------
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 )
{
|| node->getNameString() == "color-samples" )
_sampling_dirty = true;
}
+
+ _root_group->valueChanged(node);
}
//------------------------------------------------------------------------------
#include <simgear/props/props.hxx>
#include <osg/NodeCallback>
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <string>
namespace canvas
_color_dirty;
FGODGauge _texture;
+ std::auto_ptr<canvas::Group> _root_group;
SGPropertyNode_ptr _node;
std::vector<SGPropertyNode_ptr> _color_background;
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();
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)
{
}
}
+ //----------------------------------------------------------------------------
+ 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
{
class Element:
- private SGPropertyChangeListener
+ public SGPropertyChangeListener
{
public:
virtual ~Element() = 0;
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
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
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;
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()
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;
}
/**
}
// 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);
_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();
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);
else if( child->getNameString() == "stroke-width"
|| child->getNameString() == "stroke-dasharray" )
_attributes_dirty |= STROKE;
+ else if( child->getNameString() == "fill" )
+ _path->enableFill( child->getBoolValue() );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void Path::colorFillChanged(const osg::Vec4& color)
{
-
+ _path->setColorFill(color);
}
} // 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
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}