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

Revision 5328, 7.1 kB (checked in by robert, 8 years ago)

Updated copyright years.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This application is open source and may be redistributed and/or modified under 
4 * the terms of the GNU Public License (GPL) version 1.0 or
5 * (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * OpenSceneGraph Public License for more details.
11*/
12
13#include "ImageReaderWriter.h"
14
15#include <osg/Texture2D>
16#include <osg/Geometry>
17#include <osg/Geode>
18
19#include <sstream>
20
21
22ImageReaderWriter::DataReference::DataReference():
23    _fileName(),
24    _resolutionX(256),
25    _resolutionY(256),
26    _center(0.625f,0.0f,0.0f),
27    _maximumWidth(1.25f,0.0f,0.0f),
28    _maximumHeight(0.0f,0.0f,1.0f),
29    _numPointsAcross(10),
30    _numPointsUp(10),
31    _backPage(false) {}
32
33ImageReaderWriter::DataReference::DataReference(const std::string& fileName, unsigned int res, float width, float height,bool backPage):
34    _fileName(fileName),
35    _resolutionX(res),
36    _resolutionY(res),
37    _center(width*0.5f,0.0f,height*0.5f),
38    _maximumWidth(width,0.0f,0.0f),
39    _maximumHeight(0.0f,0.0f,height),
40    _numPointsAcross(10),
41    _numPointsUp(10),
42    _backPage(backPage) {}
43
44ImageReaderWriter::DataReference::DataReference(const DataReference& rhs):
45    _fileName(rhs._fileName),
46    _resolutionX(rhs._resolutionX),
47    _resolutionY(rhs._resolutionY),
48    _center(rhs._center),
49    _maximumWidth(rhs._maximumWidth),
50    _maximumHeight(rhs._maximumHeight),
51    _numPointsAcross(rhs._numPointsAcross),
52    _numPointsUp(rhs._numPointsUp),
53    _backPage(rhs._backPage) {}
54
55
56
57ImageReaderWriter::ImageReaderWriter()
58{
59}
60
61std::string ImageReaderWriter::local_insertReference(const std::string& fileName, unsigned int res, float width, float height, bool backPage)
62{
63    std::stringstream ostr;
64    ostr<<"res_"<<res<<"_"<<fileName;
65
66    std::string myReference = ostr.str();
67    _dataReferences[myReference] = DataReference(fileName,res,width,height,backPage);
68    return myReference;
69}
70
71osg::Image* ImageReaderWriter::readImage_Archive(DataReference& dr, float& s,float& t)
72{
73    for(PhotoArchiveList::iterator itr=_photoArchiveList.begin();
74        itr!=_photoArchiveList.end();
75        ++itr)
76    {
77        osg::Image* image = (*itr)->readImage(dr._fileName,dr._resolutionX,dr._resolutionY,s,t);
78        if (image) return image;
79    }
80    return 0;
81}
82
83osg::Image* ImageReaderWriter::readImage_DynamicSampling(DataReference& dr, float& s,float& t)
84{
85
86    // record previous options.
87    osg::ref_ptr<osgDB::ReaderWriter::Options> previousOptions = osgDB::Registry::instance()->getOptions();
88
89    osg::ref_ptr<osgDB::ImageOptions> options = new osgDB::ImageOptions;
90    options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW;
91    options->_destinationPixelWindow.set(0,0,dr._resolutionX,dr._resolutionY);
92
93    osgDB::Registry::instance()->setOptions(options.get());
94
95    osg::Image* image = osgDB::readImageFile(dr._fileName);
96
97    // restore previous options.
98    osgDB::Registry::instance()->setOptions(previousOptions.get());
99
100    s = options.valid()?options->_sourcePixelWindow.windowWidth:1.0f;
101    t = options.valid()?options->_sourcePixelWindow.windowHeight:1.0f;
102
103    return image;
104
105}
106
107
108osgDB::ReaderWriter::ReadResult ImageReaderWriter::local_readNode(const std::string& fileName, const Options*)
109{
110    DataReferenceMap::iterator itr = _dataReferences.find(fileName);
111    if (itr==_dataReferences.end()) return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
112
113    DataReference& dr = itr->second;
114
115    osg::Image* image = 0;
116    float s=1.0f,t=1.0f;
117   
118    // try to load photo from any loaded PhotoArchives
119    if (!_photoArchiveList.empty())
120        image = readImage_Archive(dr,s,t);
121       
122    // not loaded yet, so try to load it directly.
123    if (!image)
124        image = readImage_DynamicSampling(dr,s,t);
125
126
127    if (image)
128    {
129
130
131        float photoWidth = 0.0f;
132        float photoHeight = 0.0f;
133        float maxWidth = dr._maximumWidth.length();
134        float maxHeight = dr._maximumHeight.length();
135
136
137        if ((s/t)>(maxWidth/maxHeight))
138        {
139            // photo wider than tall relative to the required pictures size.
140            // so need to clamp the width to the maximum width and then
141            // set the height to keep the original photo aspect ratio.
142
143            photoWidth = maxWidth;
144            photoHeight = photoWidth*(t/s);
145        }
146        else
147        {
148            // photo tall than wide relative to the required pictures size.
149            // so need to clamp the height to the maximum height and then
150            // set the width to keep the original photo aspect ratio.
151
152            photoHeight = maxHeight;
153            photoWidth = photoHeight*(s/t);
154        }
155
156        photoWidth*=0.95;
157        photoHeight*=0.95;
158
159        osg::Vec3 halfWidthVector(dr._maximumWidth*(photoWidth*0.5f/maxWidth));
160        osg::Vec3 halfHeightVector(dr._maximumHeight*(photoHeight*0.5f/maxHeight));
161
162
163        // set up the texture.
164        osg::Texture2D* texture = new osg::Texture2D;
165        texture->setImage(image);
166        texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
167        texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
168
169        // set up the drawstate.
170        osg::StateSet* dstate = new osg::StateSet;
171        dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
172        dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);
173
174        // set up the geoset.
175        osg::Geometry* geom = new osg::Geometry;
176        geom->setStateSet(dstate);
177
178        osg::Vec3Array* coords = new osg::Vec3Array(4);
179
180        if (!dr._backPage)
181        {
182            (*coords)[0] = dr._center - halfWidthVector + halfHeightVector;
183            (*coords)[1] = dr._center - halfWidthVector - halfHeightVector;
184            (*coords)[2] = dr._center + halfWidthVector - halfHeightVector;
185            (*coords)[3] = dr._center + halfWidthVector + halfHeightVector;
186        }
187        else
188        {
189            (*coords)[3] = dr._center - halfWidthVector + halfHeightVector;
190            (*coords)[2] = dr._center - halfWidthVector - halfHeightVector;
191            (*coords)[1] = dr._center + halfWidthVector - halfHeightVector;
192            (*coords)[0] = dr._center + halfWidthVector + halfHeightVector;
193        }
194        geom->setVertexArray(coords);
195
196        osg::Vec2Array* tcoords = new osg::Vec2Array(4);
197        (*tcoords)[0].set(0.0f,1.0f);
198        (*tcoords)[1].set(0.0f,0.0f);
199        (*tcoords)[2].set(1.0f,0.0f);
200        (*tcoords)[3].set(1.0f,1.0f);
201        geom->setTexCoordArray(0,tcoords);
202
203        osg::Vec4Array* colours = new osg::Vec4Array(1);
204        (*colours)[0].set(1.0f,1.0f,1.0,1.0f);
205        geom->setColorArray(colours);
206        geom->setColorBinding(osg::Geometry::BIND_OVERALL);
207
208        geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
209
210        // set up the geode.
211        osg::Geode* geode = new osg::Geode;
212        geode->addDrawable(geom);
213
214        return geode;
215
216    }
217    else
218    {
219        return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
220    }
221
222
223}
Note: See TracBrowser for help on using the browser.