From 310ddbf8c5bfd6807eac79fb9cf22f6801bb80ad Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 5 Aug 2012 22:43:01 +0100 Subject: [PATCH] Initial work on Image element for Canvas. --- src/Canvas/CMakeLists.txt | 2 + src/Canvas/elements/CanvasImage.cxx | 147 ++++++++++++++++++++++++++++ src/Canvas/elements/CanvasImage.hxx | 69 +++++++++++++ src/Canvas/elements/group.cxx | 5 +- 4 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 src/Canvas/elements/CanvasImage.cxx create mode 100644 src/Canvas/elements/CanvasImage.hxx diff --git a/src/Canvas/CMakeLists.txt b/src/Canvas/CMakeLists.txt index d8c45bde1..ac1f66275 100644 --- a/src/Canvas/CMakeLists.txt +++ b/src/Canvas/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES elements/map.cxx elements/path.cxx elements/text.cxx + elements/CanvasImage.cxx gui_mgr.cxx placement.cxx property_based_element.cxx @@ -24,6 +25,7 @@ set(HEADERS elements/map.hxx elements/path.hxx elements/text.hxx + elements/CanvasImage.hxx gui_mgr.hxx placement.hxx property_based_element.hxx diff --git a/src/Canvas/elements/CanvasImage.cxx b/src/Canvas/elements/CanvasImage.cxx new file mode 100644 index 000000000..5bbed177e --- /dev/null +++ b/src/Canvas/elements/CanvasImage.cxx @@ -0,0 +1,147 @@ +// An image on the canvas +// +// Copyright (C) 2012 Thomas Geymayer +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +#include "CanvasImage.hxx" + +#include + +#include +#include +#include +#include + +#include
+#include
+ +namespace canvas +{ + //---------------------------------------------------------------------------- + Image::Image(SGPropertyNode_ptr node): + Element(node, COLOR | COLOR_FILL | BOUNDING_BOX), + _texture(new osg::Texture2D) + { + _source_rect = node->getChild("source"); + + _geom = new osg::Geometry; + _geom->setUseDisplayList(false); + + osg::StateSet *stateSet = _geom->getOrCreateStateSet(); + stateSet->setTextureAttributeAndModes(0, _texture.get()); + stateSet->setDataVariance(osg::Object::STATIC); + + // allocate arrays for the image + _vertices = new osg::Vec2Array; + _vertices->setDataVariance(osg::Object::STATIC); + _vertices->reserve(4); + _geom->setVertexArray(_vertices); + + _texCoords = new osg::Vec2Array; + _texCoords->setDataVariance(osg::Object::STATIC); + _texCoords->reserve(4); + _geom->setTexCoordArray(0, _texCoords); + + _colors = new osg::Vec4Array; + _colors->setDataVariance(osg::Object::STATIC); + _geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + _geom->setColorArray(_colors); + + osg::DrawArrays* prim = new osg::DrawArrays(osg::PrimitiveSet::QUADS); + prim->set(osg::PrimitiveSet::QUADS, 0, 1); + prim->setDataVariance(osg::Object::STATIC); + _geom->addPrimitiveSet(prim); + + setDrawable(_geom); + } + + //---------------------------------------------------------------------------- + Image::~Image() + { + + } + + //---------------------------------------------------------------------------- + void Image::update(double dt) + { + Element::update(dt); + + if( _attributes_dirty & SRC_RECT ) { + _attributes_dirty &= ~SRC_RECT; + int texWidth = _texture->getTextureWidth(); + int texHeight = _texture->getTextureHeight(); + + double x0 = _source_rect->getDoubleValue("left"), + x1 = _source_rect->getDoubleValue("right"), + y0 = _source_rect->getDoubleValue("top"), + y1 = _source_rect->getDoubleValue("bottom"); + double width = x1 - x0, height = y1 - y0; + + _vertices->clear(); + _vertices->push_back(osg::Vec2(0, 0)); + _vertices->push_back(osg::Vec2(width, 0)); + _vertices->push_back(osg::Vec2(width, height)); + _vertices->push_back(osg::Vec2(0, height)); + _vertices->dirty(); + + double u0 = x0 / texWidth, + u1 = x1 / texWidth, + v0 = y0 / texHeight, + v1 = y1 / texHeight; + + _texCoords->clear(); + _texCoords->push_back(osg::Vec2(u0, v0)); + _texCoords->push_back(osg::Vec2(u1, v0)); + _texCoords->push_back(osg::Vec2(u1, v1)); + _texCoords->push_back(osg::Vec2(u0, v1)); + _texCoords->dirty(); + } + } + + //---------------------------------------------------------------------------- + void Image::childChanged(SGPropertyNode* child) + { + const std::string& name = child->getNameString(); + + if (_source_rect == child) + _attributes_dirty |= SRC_RECT; + else if (name == "file") { + SGPath tpath = globals->resolve_ressource_path(child->getStringValue()); + if (tpath.isNull() || !tpath.exists()) { + SG_LOG(SG_GL, SG_ALERT, "canvas::Image: No such image: " << child->getStringValue()); + } else { + _texture->setImage(osgDB::readImageFile(tpath.c_str())); + _attributes_dirty |= SRC_RECT; + } + } + } + + //---------------------------------------------------------------------------- + void Image::colorChanged(const osg::Vec4& color) + { + _colors->clear(); + for (int i=0; i<4; ++i) { + _colors->push_back(color); + } + _colors->dirty(); + } + + //---------------------------------------------------------------------------- + void Image::colorFillChanged(const osg::Vec4& /*color*/) + { + } + +} // namespace canvas diff --git a/src/Canvas/elements/CanvasImage.hxx b/src/Canvas/elements/CanvasImage.hxx new file mode 100644 index 000000000..c115277d0 --- /dev/null +++ b/src/Canvas/elements/CanvasImage.hxx @@ -0,0 +1,69 @@ +// An image on the canvas +// +// Copyright (C) 2012 Thomas Geymayer +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +#ifndef CANVAS_IMAGE_HXX_ +#define CANVAS_IMAGE_HXX_ + +#include "element.hxx" + +#include + +#include +#include + +#include + +namespace canvas +{ + + class Image: + public Element + { + public: + Image(SGPropertyNode_ptr node); + ~Image(); + + virtual void update(double dt); + + protected: + + enum TextAttributes + { + SRC_RECT = LAST_ATTRIBUTE << 1, // Source image rectangle + }; + + SGPropertyNode_ptr _source_rect, + _dest_rect; + + virtual void childChanged(SGPropertyNode * child); + virtual void colorChanged(const osg::Vec4& color); + virtual void colorFillChanged(const osg::Vec4& color); + + void handleHit(float x, float y); + + osg::ref_ptr _texture; + + osg::Geometry *_geom; + osg::Vec2Array *_vertices; + osg::Vec2Array *_texCoords; + osg::Vec4Array* _colors; + }; + +} // namespace canvas + +#endif /* CANVAS_IMAGE_HXX_ */ diff --git a/src/Canvas/elements/group.cxx b/src/Canvas/elements/group.cxx index 96eb49c23..473ecc2f5 100644 --- a/src/Canvas/elements/group.cxx +++ b/src/Canvas/elements/group.cxx @@ -20,6 +20,7 @@ #include "map.hxx" #include "path.hxx" #include "text.hxx" +#include "CanvasImage.hxx" namespace canvas { @@ -61,7 +62,9 @@ namespace canvas element.reset( new Map(child) ); else if( child->getNameString() == "path" ) element.reset( new Path(child) ); - + else if( child->getNameString() == "image" ) + element.reset( new Image(child) ); + if( !element ) return;