2 ******************************************************************************
4 * @file OSGImageNode.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "OSGImageNode.hpp"
30 #include "utils/imagesource.hpp"
33 #include "utils/gstreamer/gstimagesource.hpp"
37 #include <osg/Geometry>
39 #include <osg/Texture2D>
44 namespace osgQtQuick
{
45 enum DirtyFlag
{ ImageFile
= 1 << 0 };
47 struct OSGImageNode::Hidden
: public QObject
{
51 OSGImageNode
* const self
;
53 osg::ref_ptr
<osg::Texture2D
> texture
;
55 ImageSource
*imageSource
;
60 Hidden(OSGImageNode
*self
) : QObject(self
), self(self
), imageSource(NULL
), imageUrl()
67 osg::Node
*createNode()
69 osg::Geode
*geode
= new osg::Geode
;
74 osg::Image
*loadImage()
77 if (imageUrl
.scheme() == "gst") {
79 imageSource
= new GstImageSource();
81 qWarning() << "gstreamer image source is not supported";
84 imageSource
= new ImageSource();
87 return imageSource
? imageSource
->createImage(imageUrl
) : 0;
90 void updateImageFile()
97 osg::Image
*image
= loadImage();
103 // qDebug() << "OSGImageNode::update" << image;
104 osg::Node
*geode
= createGeodeForImage(image
);
106 self
->setNode(geode
);
109 osg::Geode
*createGeodeForImage(osg::Image
*image
)
112 osg::Vec3Array
*coords
= new osg::Vec3Array(4);
114 (*coords
)[0].set(0, 1, 0);
115 (*coords
)[1].set(0, 0, 0);
116 (*coords
)[2].set(1, 0, 0);
117 (*coords
)[3].set(1, 1, 0);
120 osg::Vec2Array
*texcoords
= new osg::Vec2Array(4);
123 float y_b
= (image
->getOrigin() == osg::Image::BOTTOM_LEFT
) ? 0.0f
: 1.0f
;
124 float y_t
= (image
->getOrigin() == osg::Image::BOTTOM_LEFT
) ? 1.0f
: 0.0f
;
125 (*texcoords
)[0].set(x_b
, y_t
);
126 (*texcoords
)[1].set(x_b
, y_b
);
127 (*texcoords
)[2].set(x_t
, y_b
);
128 (*texcoords
)[3].set(x_t
, y_t
);
131 osg::Vec4Array
*color
= new osg::Vec4Array(1);
132 (*color
)[0].set(1.0f
, 1.0f
, 1.0f
, 1.0f
);
134 // setup the geometry
135 osg::Geometry
*geom
= new osg::Geometry
;
136 geom
->setVertexArray(coords
);
137 geom
->setTexCoordArray(0, texcoords
);
138 geom
->setColorArray(color
, osg::Array::BIND_OVERALL
);
139 geom
->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS
, 0, 4));
141 // set up the texture.
142 osg::Texture2D
*texture
= new osg::Texture2D
;
143 texture
->setFilter(osg::Texture::MIN_FILTER
, osg::Texture::LINEAR
);
144 texture
->setFilter(osg::Texture::MAG_FILTER
, osg::Texture::LINEAR
);
145 texture
->setResizeNonPowerOfTwoHint(false);
146 texture
->setImage(image
);
149 osg::StateSet
*state
= new osg::StateSet
;
150 state
->setMode(GL_CULL_FACE
, osg::StateAttribute::OFF
);
151 state
->setMode(GL_LIGHTING
, osg::StateAttribute::OFF
);
152 state
->setTextureAttributeAndModes(0, texture
, osg::StateAttribute::ON
);
153 geom
->setStateSet(state
);
156 osg::Geode
*geode
= new osg::Geode
;
157 geode
->addDrawable(geom
);
163 /* class OSGImageNode */
165 OSGImageNode::OSGImageNode(QObject
*parent
) : Inherited(parent
), h(new Hidden(this))
168 OSGImageNode::~OSGImageNode()
173 const QUrl
OSGImageNode::imageUrl() const
178 void OSGImageNode::setImageUrl(QUrl
&url
)
180 if (h
->imageUrl
!= url
) {
183 emit
imageUrlChanged(url
);
187 osg::Node
*OSGImageNode::createNode()
189 return h
->createNode();
192 void OSGImageNode::updateNode()
194 Inherited::updateNode();
196 if (isDirty(ImageFile
)) {
197 h
->updateImageFile();
200 } // namespace osgQtQuick
202 #include "OSGImageNode.moc"