Merged in f5soh/librepilot/LP-575_fedora_package (pull request #491)
[librepilot.git] / ground / gcs / src / libs / osgearth / osgQtQuick / OSGImageNode.cpp
blobf2e8712ca129d2fa8a3071bc15c9f0faf1a06c02
1 /**
2 ******************************************************************************
4 * @file OSGImageNode.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
6 * @addtogroup
7 * @{
8 * @addtogroup
9 * @{
10 * @brief
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
21 * for more details.
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"
32 #ifdef USE_GSTREAMER
33 #include "utils/gstreamer/gstimagesource.hpp"
34 #endif
36 #include <osg/Image>
37 #include <osg/Geometry>
38 #include <osg/Geode>
39 #include <osg/Texture2D>
41 #include <QUrl>
42 #include <QDebug>
44 namespace osgQtQuick {
45 enum DirtyFlag { ImageFile = 1 << 0 };
47 struct OSGImageNode::Hidden : public QObject {
48 Q_OBJECT
50 private:
51 OSGImageNode * const self;
53 osg::ref_ptr<osg::Texture2D> texture;
55 ImageSource *imageSource;
57 public:
58 QUrl imageUrl;
60 Hidden(OSGImageNode *self) : QObject(self), self(self), imageSource(NULL), imageUrl()
62 if (imageSource) {
63 delete imageSource;
67 osg::Node *createNode()
69 osg::Geode *geode = new osg::Geode;
71 return geode;
74 osg::Image *loadImage()
76 if (!imageSource) {
77 if (imageUrl.scheme() == "gst") {
78 #ifdef USE_GSTREAMER
79 imageSource = new GstImageSource();
80 #else
81 qWarning() << "gstreamer image source is not supported";
82 #endif
83 } else {
84 imageSource = new ImageSource();
87 return imageSource ? imageSource->createImage(imageUrl) : 0;
90 void updateImageFile()
92 update();
95 void update()
97 osg::Image *image = loadImage();
99 if (!image) {
100 return;
103 // qDebug() << "OSGImageNode::update" << image;
104 osg::Node *geode = createGeodeForImage(image);
106 self->setNode(geode);
109 osg::Geode *createGeodeForImage(osg::Image *image)
111 // vertex
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);
119 // texture coords
120 osg::Vec2Array *texcoords = new osg::Vec2Array(4);
121 float x_b = 0.0f;
122 float x_t = 1.0f;
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);
130 // color
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);
148 // set up the state.
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);
155 // set up the geode.
156 osg::Geode *geode = new osg::Geode;
157 geode->addDrawable(geom);
159 return geode;
163 /* class OSGImageNode */
165 OSGImageNode::OSGImageNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
168 OSGImageNode::~OSGImageNode()
170 delete h;
173 const QUrl OSGImageNode::imageUrl() const
175 return h->imageUrl;
178 void OSGImageNode::setImageUrl(QUrl &url)
180 if (h->imageUrl != url) {
181 h->imageUrl = url;
182 setDirty(ImageFile);
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"