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

Revision 13576, 7.6 kB (checked in by robert, 2 days ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

  • 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, osg::Array::BIND_OVERALL);
214
215        geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
216
217        // set up the geode.
218        osg::Geode* geode = new osg::Geode;
219        geode->addDrawable(geom);
220
221        return geode;
222
223    }
224    else
225    {
226        return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
227    }
228
229
230}
Note: See TracBrowser for help on using the browser.