root/OpenSceneGraph/trunk/examples/osgphotoalbum/ImageReaderWriter.cpp @ 13449

Revision 13449, 7.6 kB (checked in by robert, 27 minutes ago)

From Mattias Helsing, "Seems I was only half right given what you asked for. CMP0017 only
says that modules that are found and ran from cmake modules dir should
prefer cmake-provided modules. find_package() and include() still look
in CMAKE_MODULE_PATH first.

After some investigating I've come up with a proposal examplified in
the attached FindGDAL.cmake script. It simply calls the cmake provided
FindGDAL.cmake if it exists and returns if it succeeds in finding GDAL
using that, otherwise continue with our local cmake code.
Pro: Wont clutter our root CMakeLists.txt
Con: If we begin to write more advanced Findxxx modules (using
COMPONENTS, REQUIRED etc.) we may have to revise this scheme.
"

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgphotoalbum.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19
20#include "ImageReaderWriter.h"
21
22#include <osg/Texture2D>
23#include <osg/Geometry>
24#include <osg/Geode>
25
26#include <sstream>
27
28
29ImageReaderWriter::DataReference::DataReference():
30    _fileName(),
31    _resolutionX(256),
32    _resolutionY(256),
33    _center(0.625f,0.0f,0.0f),
34    _maximumWidth(1.25f,0.0f,0.0f),
35    _maximumHeight(0.0f,0.0f,1.0f),
36    _numPointsAcross(10),
37    _numPointsUp(10),
38    _backPage(false) {}
39
40ImageReaderWriter::DataReference::DataReference(const std::string& fileName, unsigned int res, float width, float height,bool backPage):
41    _fileName(fileName),
42    _resolutionX(res),
43    _resolutionY(res),
44    _center(width*0.5f,0.0f,height*0.5f),
45    _maximumWidth(width,0.0f,0.0f),
46    _maximumHeight(0.0f,0.0f,height),
47    _numPointsAcross(10),
48    _numPointsUp(10),
49    _backPage(backPage) {}
50
51ImageReaderWriter::DataReference::DataReference(const DataReference& rhs):
52    _fileName(rhs._fileName),
53    _resolutionX(rhs._resolutionX),
54    _resolutionY(rhs._resolutionY),
55    _center(rhs._center),
56    _maximumWidth(rhs._maximumWidth),
57    _maximumHeight(rhs._maximumHeight),
58    _numPointsAcross(rhs._numPointsAcross),
59    _numPointsUp(rhs._numPointsUp),
60    _backPage(rhs._backPage) {}
61
62
63
64ImageReaderWriter::ImageReaderWriter()
65{
66}
67
68std::string ImageReaderWriter::local_insertReference(const std::string& fileName, unsigned int res, float width, float height, bool backPage)
69{
70    std::stringstream ostr;
71    ostr<<"res_"<<res<<"_"<<fileName;
72
73    std::string myReference = ostr.str();
74    _dataReferences[myReference] = DataReference(fileName,res,width,height,backPage);
75    return myReference;
76}
77
78osg::Image* ImageReaderWriter::readImage_Archive(DataReference& dr, float& s,float& t)
79{
80    for(PhotoArchiveList::iterator itr=_photoArchiveList.begin();
81        itr!=_photoArchiveList.end();
82        ++itr)
83    {
84        osg::Image* image = (*itr)->readImage(dr._fileName,dr._resolutionX,dr._resolutionY,s,t);
85        if (image) return image;
86    }
87    return 0;
88}
89
90osg::Image* ImageReaderWriter::readImage_DynamicSampling(DataReference& dr, float& s,float& t)
91{
92
93    // record previous options.
94    osg::ref_ptr<osgDB::ReaderWriter::Options> previousOptions = osgDB::Registry::instance()->getOptions();
95
96    osg::ref_ptr<osgDB::ImageOptions> options = new osgDB::ImageOptions;
97    options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW;
98    options->_destinationPixelWindow.set(0,0,dr._resolutionX,dr._resolutionY);
99
100    osgDB::Registry::instance()->setOptions(options.get());
101
102    osg::Image* image = osgDB::readImageFile(dr._fileName);
103
104    // restore previous options.
105    osgDB::Registry::instance()->setOptions(previousOptions.get());
106
107    s = options.valid()?options->_sourcePixelWindow.windowWidth:1.0f;
108    t = options.valid()?options->_sourcePixelWindow.windowHeight:1.0f;
109
110    return image;
111
112}
113
114
115osgDB::ReaderWriter::ReadResult ImageReaderWriter::local_readNode(const std::string& fileName, const Options*)
116{
117    DataReferenceMap::iterator itr = _dataReferences.find(fileName);
118    if (itr==_dataReferences.end()) return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
119
120    DataReference& dr = itr->second;
121
122    osg::Image* image = 0;
123    float s=1.0f,t=1.0f;
124   
125    // try to load photo from any loaded PhotoArchives
126    if (!_photoArchiveList.empty())
127        image = readImage_Archive(dr,s,t);
128       
129    // not loaded yet, so try to load it directly.
130    if (!image)
131        image = readImage_DynamicSampling(dr,s,t);
132
133
134    if (image)
135    {
136
137
138        float photoWidth = 0.0f;
139        float photoHeight = 0.0f;
140        float maxWidth = dr._maximumWidth.length();
141        float maxHeight = dr._maximumHeight.length();
142
143
144        if ((s/t)>(maxWidth/maxHeight))
145        {
146            // photo wider than tall relative to the required pictures size.
147            // so need to clamp the width to the maximum width and then
148            // set the height to keep the original photo aspect ratio.
149
150            photoWidth = maxWidth;
151            photoHeight = photoWidth*(t/s);
152        }
153        else
154        {
155            // photo tall than wide relative to the required pictures size.
156            // so need to clamp the height to the maximum height and then
157            // set the width to keep the original photo aspect ratio.
158
159            photoHeight = maxHeight;
160            photoWidth = photoHeight*(s/t);
161        }
162
163        photoWidth*=0.95;
164        photoHeight*=0.95;
165
166        osg::Vec3 halfWidthVector(dr._maximumWidth*(photoWidth*0.5f/maxWidth));
167        osg::Vec3 halfHeightVector(dr._maximumHeight*(photoHeight*0.5f/maxHeight));
168
169
170        // set up the texture.
171        osg::Texture2D* texture = new osg::Texture2D;
172        texture->setImage(image);
173        texture->setResizeNonPowerOfTwoHint(false);
174        texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
175        texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
176
177        // set up the drawstate.
178        osg::StateSet* dstate = new osg::StateSet;
179        dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
180        dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);
181
182        // set up the geoset.
183        osg::Geometry* geom = new osg::Geometry;
184        geom->setStateSet(dstate);
185
186        osg::Vec3Array* coords = new osg::Vec3Array(4);
187
188        if (!dr._backPage)
189        {
190            (*coords)[0] = dr._center - halfWidthVector + halfHeightVector;
191            (*coords)[1] = dr._center - halfWidthVector - halfHeightVector;
192            (*coords)[2] = dr._center + halfWidthVector - halfHeightVector;
193            (*coords)[3] = dr._center + halfWidthVector + halfHeightVector;
194        }
195        else
196        {
197            (*coords)[3] = dr._center - halfWidthVector + halfHeightVector;
198            (*coords)[2] = dr._center - halfWidthVector - halfHeightVector;
199            (*coords)[1] = dr._center + halfWidthVector - halfHeightVector;
200            (*coords)[0] = dr._center + halfWidthVector + halfHeightVector;
201        }
202        geom->setVertexArray(coords);
203
204        osg::Vec2Array* tcoords = new osg::Vec2Array(4);
205        (*tcoords)[0].set(0.0f,1.0f);
206        (*tcoords)[1].set(0.0f,0.0f);
207        (*tcoords)[2].set(1.0f,0.0f);
208        (*tcoords)[3].set(1.0f,1.0f);
209        geom->setTexCoordArray(0,tcoords);
210
211        osg::Vec4Array* colours = new osg::Vec4Array(1);
212        (*colours)[0].set(1.0f,1.0f,1.0,1.0f);
213        geom->setColorArray(colours);
214        geom->setColorBinding(osg::Geometry::BIND_OVERALL);
215
216        geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
217
218        // set up the geode.
219        osg::Geode* geode = new osg::Geode;
220        geode->addDrawable(geom);
221
222        return geode;
223
224    }
225    else
226    {
227        return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
228    }
229
230
231}
Note: See TracBrowser for help on using the browser.