From ca7a80685defeb14ef624665df2d64ac318ac6b9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 22 Dec 2003 21:05:10 +0000 Subject: [PATCH] Added beginings of PhotoArchive for storing and loading a set of photos from an archive. --- examples/osgphotoalbum/GNUmakefile | 2 + examples/osgphotoalbum/ImageReaderWriter.cpp | 215 +++++++++++++++++++ examples/osgphotoalbum/ImageReaderWriter.h | 71 ++++++ examples/osgphotoalbum/PhotoArchive.cpp | 14 ++ examples/osgphotoalbum/PhotoArchive.h | 10 + examples/osgphotoalbum/osgphotoalbum.cpp | 214 +----------------- 6 files changed, 319 insertions(+), 207 deletions(-) create mode 100644 examples/osgphotoalbum/ImageReaderWriter.cpp create mode 100644 examples/osgphotoalbum/ImageReaderWriter.h create mode 100644 examples/osgphotoalbum/PhotoArchive.cpp create mode 100644 examples/osgphotoalbum/PhotoArchive.h diff --git a/examples/osgphotoalbum/GNUmakefile b/examples/osgphotoalbum/GNUmakefile index 9047e33e7..5fde5f176 100644 --- a/examples/osgphotoalbum/GNUmakefile +++ b/examples/osgphotoalbum/GNUmakefile @@ -2,6 +2,8 @@ TOPDIR = ../.. include $(TOPDIR)/Make/makedefs CXXFILES =\ + ImageReaderWriter.cpp\ + PhotoArchive.cpp\ osgphotoalbum.cpp\ LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) diff --git a/examples/osgphotoalbum/ImageReaderWriter.cpp b/examples/osgphotoalbum/ImageReaderWriter.cpp new file mode 100644 index 000000000..94699a51c --- /dev/null +++ b/examples/osgphotoalbum/ImageReaderWriter.cpp @@ -0,0 +1,215 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This application is open source and may be redistributed and/or modified under + * the terms of the GNU Public License (GPL) version 1.0 or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include "ImageReaderWriter.h" + +#include +#include +#include + +#include + + +ImageReaderWriter::DataReference::DataReference(): + _fileName(), + _resolutionX(256), + _resolutionY(256), + _center(0.625f,0.0f,0.0f), + _maximumWidth(1.25f,0.0f,0.0f), + _maximumHeight(0.0f,0.0f,1.0f), + _numPointsAcross(10), + _numPointsUp(10), + _backPage(false) {} + +ImageReaderWriter::DataReference::DataReference(const std::string& fileName, unsigned int res, float width, float height,bool backPage): + _fileName(fileName), + _resolutionX(res), + _resolutionY(res), + _center(width*0.5f,0.0f,height*0.5f), + _maximumWidth(width,0.0f,0.0f), + _maximumHeight(0.0f,0.0f,height), + _numPointsAcross(10), + _numPointsUp(10), + _backPage(backPage) {} + +ImageReaderWriter::DataReference::DataReference(const DataReference& rhs): + _fileName(rhs._fileName), + _resolutionX(rhs._resolutionX), + _resolutionY(rhs._resolutionY), + _center(rhs._center), + _maximumWidth(rhs._maximumWidth), + _maximumHeight(rhs._maximumHeight), + _numPointsAcross(rhs._numPointsAcross), + _numPointsUp(rhs._numPointsUp), + _backPage(rhs._backPage) {} + + + +ImageReaderWriter::ImageReaderWriter() +{ +} + +std::string ImageReaderWriter::insertReference(const std::string& fileName, unsigned int res, float width, float height, bool backPage) +{ + std::stringstream ostr; + ostr<<"res_"< previousOptions = osgDB::Registry::instance()->getOptions(); + + osg::ref_ptr options = new osgDB::ImageOptions; + options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW; + options->_destinationPixelWindow.set(0,0,dr._resolutionX,dr._resolutionY); + + osgDB::Registry::instance()->setOptions(options.get()); + + osg::Image* image = osgDB::readImageFile(dr._fileName); + + // restore previous options. + osgDB::Registry::instance()->setOptions(previousOptions.get()); + + s = options.valid()?options->_sourcePixelWindow.windowWidth:1.0f; + t = options.valid()?options->_sourcePixelWindow.windowHeight:1.0f; + + return image; + +} + + +osgDB::ReaderWriter::ReadResult ImageReaderWriter::readNode(const std::string& fileName, const Options*) +{ + std::cout<<"Request to read paged image "<second; + + osg::Image* image = 0; + float s=1.0f,t=1.0f; + + if (_photoArchive.valid()) + image = readImage_Archive(dr,s,t); + else + image = readImage_DynamicSampling(dr,s,t); + + + if (image) + { + + + float photoWidth = 0.0f; + float photoHeight = 0.0f; + float maxWidth = dr._maximumWidth.length(); + float maxHeight = dr._maximumHeight.length(); + + + if ((s/t)>(maxWidth/maxHeight)) + { + // photo wider than tall relative to the required pictures size. + // so need to clamp the width to the maximum width and then + // set the height to keep the original photo aspect ratio. + + photoWidth = maxWidth; + photoHeight = photoWidth*(t/s); + } + else + { + // photo tall than wide relative to the required pictures size. + // so need to clamp the height to the maximum height and then + // set the width to keep the original photo aspect ratio. + + photoHeight = maxHeight; + photoWidth = photoHeight*(s/t); + } + + photoWidth*=0.95; + photoHeight*=0.95; + + osg::Vec3 halfWidthVector(dr._maximumWidth*(photoWidth*0.5f/maxWidth)); + osg::Vec3 halfHeightVector(dr._maximumHeight*(photoHeight*0.5f/maxHeight)); + + + // set up the texture. + osg::Texture2D* texture = new osg::Texture2D; + texture->setImage(image); + texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); + texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); + + // set up the drawstate. + osg::StateSet* dstate = new osg::StateSet; + dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF); + dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); + + // set up the geoset. + osg::Geometry* geom = new osg::Geometry; + geom->setStateSet(dstate); + + osg::Vec3Array* coords = new osg::Vec3Array(4); + + if (!dr._backPage) + { + (*coords)[0] = dr._center - halfWidthVector + halfHeightVector; + (*coords)[1] = dr._center - halfWidthVector - halfHeightVector; + (*coords)[2] = dr._center + halfWidthVector - halfHeightVector; + (*coords)[3] = dr._center + halfWidthVector + halfHeightVector; + } + else + { + (*coords)[3] = dr._center - halfWidthVector + halfHeightVector; + (*coords)[2] = dr._center - halfWidthVector - halfHeightVector; + (*coords)[1] = dr._center + halfWidthVector - halfHeightVector; + (*coords)[0] = dr._center + halfWidthVector + halfHeightVector; + } + geom->setVertexArray(coords); + + osg::Vec2Array* tcoords = new osg::Vec2Array(4); + (*tcoords)[0].set(0.0f,1.0f); + (*tcoords)[1].set(0.0f,0.0f); + (*tcoords)[2].set(1.0f,0.0f); + (*tcoords)[3].set(1.0f,1.0f); + geom->setTexCoordArray(0,tcoords); + + osg::Vec4Array* colours = new osg::Vec4Array(1); + (*colours)[0].set(1.0f,1.0f,1.0,1.0f); + geom->setColorArray(colours); + geom->setColorBinding(osg::Geometry::BIND_OVERALL); + + geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); + + // set up the geode. + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geom); + + return geode; + + } + else + { + return ReaderWriter::ReadResult::FILE_NOT_HANDLED; + } + + +} diff --git a/examples/osgphotoalbum/ImageReaderWriter.h b/examples/osgphotoalbum/ImageReaderWriter.h new file mode 100644 index 000000000..2bbf1713e --- /dev/null +++ b/examples/osgphotoalbum/ImageReaderWriter.h @@ -0,0 +1,71 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This application is open source and may be redistributed and/or modified under + * the terms of the GNU Public License (GPL) version 1.0 or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef IMAGEREADERWRITER_H +#define IMAGEREADERWRITER_H + +#include +#include +#include + +#include "PhotoArchive.h" + +class ImageReaderWriter : public osgDB::ReaderWriter +{ + public: + + ImageReaderWriter(); + + virtual const char* className() { return "ImageReader"; } + + void setPhotoArchive(PhotoArchive* archive) { _photoArchive = archive; } + PhotoArchive* getPhotoArchive() { return _photoArchive.get(); } + const PhotoArchive* getPhotoArchive() const { return _photoArchive.get(); } + + std::string insertReference(const std::string& fileName, unsigned int res, float width, float height, bool backPage); + + + virtual ReadResult readNode(const std::string& fileName, const Options*); + + protected: + + + struct DataReference + { + DataReference(); + DataReference(const std::string& fileName, unsigned int res, float width, float height,bool backPage); + DataReference(const DataReference& rhs); + + std::string _fileName; + unsigned int _resolutionX; + unsigned int _resolutionY; + osg::Vec3 _center; + osg::Vec3 _maximumWidth; + osg::Vec3 _maximumHeight; + unsigned int _numPointsAcross; + unsigned int _numPointsUp; + bool _backPage; + }; + + osg::Image* readImage_Archive(DataReference& dr, float& s,float& t); + + osg::Image* readImage_DynamicSampling(DataReference& dr, float& s,float& t); + + typedef std::map DataReferenceMap; + + DataReferenceMap _dataReferences; + osg::ref_ptr _photoArchive; + + +}; + +#endif diff --git a/examples/osgphotoalbum/PhotoArchive.cpp b/examples/osgphotoalbum/PhotoArchive.cpp new file mode 100644 index 000000000..b7aac2ae6 --- /dev/null +++ b/examples/osgphotoalbum/PhotoArchive.cpp @@ -0,0 +1,14 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This application is open source and may be redistributed and/or modified under + * the terms of the GNU Public License (GPL) version 1.0 or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include "PhotoArchive.h" + diff --git a/examples/osgphotoalbum/PhotoArchive.h b/examples/osgphotoalbum/PhotoArchive.h new file mode 100644 index 000000000..015e3b75c --- /dev/null +++ b/examples/osgphotoalbum/PhotoArchive.h @@ -0,0 +1,10 @@ +#ifndef PHOTOARCHIVE_H +#define PHOTOARCHIVE_H + +#include + +class PhotoArchive : public osg::Referenced +{ +}; + +#endif diff --git a/examples/osgphotoalbum/osgphotoalbum.cpp b/examples/osgphotoalbum/osgphotoalbum.cpp index f528615b7..58fc7427b 100644 --- a/examples/osgphotoalbum/osgphotoalbum.cpp +++ b/examples/osgphotoalbum/osgphotoalbum.cpp @@ -1,9 +1,8 @@ /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield * - * This library is open source and may be redistributed and/or modified under - * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or - * (at your option) any later version. The full license is in LICENSE file - * included with this distribution, and on the openscenegraph.org website. + * This application is open source and may be redistributed and/or modified under + * the terms of the GNU Public License (GPL) version 1.0 or + * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -11,222 +10,23 @@ * OpenSceneGraph Public License for more details. */ -#include #include #include #include -#include -#include #include #include #include -#include -#include -#include - #include #include -#include +#include "ImageReaderWriter.h" -class ImageReaderWriter : public osgDB::ReaderWriter -{ - public: - virtual const char* className() { return "Image Reader"; } - - - struct DataReference - { - DataReference(): - _fileName(), - _resolutionX(256), - _resolutionY(256), - _center(0.625f,0.0f,0.0f), - _maximumWidth(1.25f,0.0f,0.0f), - _maximumHeight(0.0f,0.0f,1.0f), - _numPointsAcross(10), - _numPointsUp(10), - _backPage(false) {} - - DataReference(const std::string& fileName, unsigned int res, float width, float height,bool backPage): - _fileName(fileName), - _resolutionX(res), - _resolutionY(res), - _center(width*0.5f,0.0f,height*0.5f), - _maximumWidth(width,0.0f,0.0f), - _maximumHeight(0.0f,0.0f,height), - _numPointsAcross(10), - _numPointsUp(10), - _backPage(backPage) {} - - DataReference(const DataReference& rhs): - _fileName(rhs._fileName), - _resolutionX(rhs._resolutionX), - _resolutionY(rhs._resolutionY), - _center(rhs._center), - _maximumWidth(rhs._maximumWidth), - _maximumHeight(rhs._maximumHeight), - _numPointsAcross(rhs._numPointsAcross), - _numPointsUp(rhs._numPointsUp), - _backPage(rhs._backPage) {} - - std::string _fileName; - unsigned int _resolutionX; - unsigned int _resolutionY; - osg::Vec3 _center; - osg::Vec3 _maximumWidth; - osg::Vec3 _maximumHeight; - unsigned int _numPointsAcross; - unsigned int _numPointsUp; - bool _backPage; - }; - - typedef std::map DataReferenceMap; - DataReferenceMap _dataReferences; - - std::string insertReference(const std::string& fileName, unsigned int res, float width, float height, bool backPage) - { - std::stringstream ostr; - ostr<<"res_"<second; - - // record previous options. - osg::ref_ptr previousOptions = osgDB::Registry::instance()->getOptions(); - - osg::ref_ptr options = new osgDB::ImageOptions; - options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW; - options->_destinationPixelWindow.set(0,0,dr._resolutionX,dr._resolutionY); - - osgDB::Registry::instance()->setOptions(options.get()); - - osg::Image* image = osgDB::readImageFile(dr._fileName); - - // restore previous options. - osgDB::Registry::instance()->setOptions(previousOptions.get()); - - if (image) - { - - float s = options.valid()?options->_sourcePixelWindow.windowWidth:1.0f; - float t = options.valid()?options->_sourcePixelWindow.windowHeight:1.0f; - - float photoWidth = 0.0f; - float photoHeight = 0.0f; - float maxWidth = dr._maximumWidth.length(); - float maxHeight = dr._maximumHeight.length(); - - - if ((s/t)>(maxWidth/maxHeight)) - { - // photo wider than tall relative to the required pictures size. - // so need to clamp the width to the maximum width and then - // set the height to keep the original photo aspect ratio. - - photoWidth = maxWidth; - photoHeight = photoWidth*(t/s); - } - else - { - // photo tall than wide relative to the required pictures size. - // so need to clamp the height to the maximum height and then - // set the width to keep the original photo aspect ratio. - - photoHeight = maxHeight; - photoWidth = photoHeight*(s/t); - } - - photoWidth*=0.95; - photoHeight*=0.95; - - osg::Vec3 halfWidthVector(dr._maximumWidth*(photoWidth*0.5f/maxWidth)); - osg::Vec3 halfHeightVector(dr._maximumHeight*(photoHeight*0.5f/maxHeight)); - - - // set up the texture. - osg::Texture2D* texture = new osg::Texture2D; - texture->setImage(image); - texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); - texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); - - // set up the drawstate. - osg::StateSet* dstate = new osg::StateSet; - dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF); - dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); - - // set up the geoset. - osg::Geometry* geom = new osg::Geometry; - geom->setStateSet(dstate); - - osg::Vec3Array* coords = new osg::Vec3Array(4); - - if (!dr._backPage) - { - (*coords)[0] = dr._center - halfWidthVector + halfHeightVector; - (*coords)[1] = dr._center - halfWidthVector - halfHeightVector; - (*coords)[2] = dr._center + halfWidthVector - halfHeightVector; - (*coords)[3] = dr._center + halfWidthVector + halfHeightVector; - } - else - { - (*coords)[3] = dr._center - halfWidthVector + halfHeightVector; - (*coords)[2] = dr._center - halfWidthVector - halfHeightVector; - (*coords)[1] = dr._center + halfWidthVector - halfHeightVector; - (*coords)[0] = dr._center + halfWidthVector + halfHeightVector; - } - geom->setVertexArray(coords); - - osg::Vec2Array* tcoords = new osg::Vec2Array(4); - (*tcoords)[0].set(0.0f,1.0f); - (*tcoords)[1].set(0.0f,0.0f); - (*tcoords)[2].set(1.0f,0.0f); - (*tcoords)[3].set(1.0f,1.0f); - geom->setTexCoordArray(0,tcoords); - - osg::Vec4Array* colours = new osg::Vec4Array(1); - (*colours)[0].set(1.0f,1.0f,1.0,1.0f); - geom->setColorArray(colours); - geom->setColorBinding(osg::Geometry::BIND_OVERALL); - - geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); - - // set up the geode. - osg::Geode* geode = new osg::Geode; - geode->addDrawable(geom); - - return geode; - - } - else - { - return ReaderWriter::ReadResult::FILE_NOT_HANDLED; - } - - - } - -}; - - -// now register with Registry to instantiate the above -// reader/writer. +// now register with Registry to instantiate the above reader/writer, +// declaring in main so that the code to set up PagedLOD can get a handle +// to the ImageReaderWriter's osgDB::RegisterReaderWriterProxy g_ImageReaderWriter; class Album;