diff --git a/examples/osgdem/GNUmakefile b/examples/osgdem/GNUmakefile index a6ae3e106..dfbbd656d 100644 --- a/examples/osgdem/GNUmakefile +++ b/examples/osgdem/GNUmakefile @@ -4,7 +4,7 @@ include $(TOPDIR)/Make/makedefs CXXFILES =\ osgdem.cpp\ -LIBS += -losgProducer -lProducer -losgFX -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) +LIBS += -losgProducer -lProducer -losgFX -losgGL2 -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) INSTFILES = \ $(CXXFILES)\ diff --git a/examples/osgdem/GNUmakefile.inst b/examples/osgdem/GNUmakefile.inst index d27395804..b2c0aaba7 100644 --- a/examples/osgdem/GNUmakefile.inst +++ b/examples/osgdem/GNUmakefile.inst @@ -4,7 +4,7 @@ include $(TOPDIR)/Make/makedefs CXXFILES =\ osgdem.cpp\ -LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) +LIBS += -losgProducer -lProducer -losgFX -losgGL2 -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) EXEC = osgdem diff --git a/examples/osgdem/osgdem.cpp b/examples/osgdem/osgdem.cpp index bee5453cb..fd9f45385 100644 --- a/examples/osgdem/osgdem.cpp +++ b/examples/osgdem/osgdem.cpp @@ -349,7 +349,8 @@ osg::Node* createQuadTree(osg::HeightField* grid, unsigned int rowBegin, unsigned int rowEnd, float xTexCoordBegin, float xTexCoordEnd, float yTexCoordBegin, float yTexCoordEnd, - unsigned int targetNumPolygonsPerTile) + unsigned int targetNumPolygonsPerTile, + unsigned int numLevels) { unsigned int numPolys = (columnEnd-columnBegin)*(rowEnd-rowBegin)*2; @@ -363,7 +364,7 @@ osg::Node* createQuadTree(osg::HeightField* grid, yTexCoordBegin, yTexCoordEnd, targetNumPolygonsPerTile); - if (numPolys<=targetNumPolygonsPerTile) + if (numPolys<=targetNumPolygonsPerTile || numLevels==0) { return tile; } @@ -385,28 +386,32 @@ osg::Node* createQuadTree(osg::HeightField* grid, rowBegin, rowCenter, xTexCoordBegin, xTexCoordCenter, yTexCoordBegin, yTexCoordCenter, - targetNumPolygonsPerTile)); + targetNumPolygonsPerTile, + numLevels-1)); group->addChild(createQuadTree(grid, columnCenter, columnEnd, rowBegin, rowCenter, xTexCoordCenter, xTexCoordEnd, yTexCoordBegin, yTexCoordCenter, - targetNumPolygonsPerTile)); + targetNumPolygonsPerTile, + numLevels-1)); group->addChild(createQuadTree(grid, columnCenter, columnEnd, rowCenter, rowEnd, xTexCoordCenter, xTexCoordEnd, yTexCoordCenter, yTexCoordEnd, - targetNumPolygonsPerTile)); + targetNumPolygonsPerTile, + numLevels-1)); group->addChild(createQuadTree(grid, columnBegin, columnCenter, rowCenter, rowEnd, xTexCoordBegin, xTexCoordCenter, yTexCoordCenter, yTexCoordEnd, - targetNumPolygonsPerTile)); + targetNumPolygonsPerTile, + numLevels-1)); osg::LOD* lod = new osg::LOD; lod->addChild(tile,cut_off_distance,max_visible_distance); @@ -679,7 +684,7 @@ osg::Node* createTileAndRecurse(const std::string& filename, const std::string& } -bool createWorld(const std::string& inputFile, const std::string& baseName, unsigned int numLevels) +bool createWorld(const std::string& inputFile, const std::string& baseName, const std::string& diffuseTextureName,unsigned int numLevels) { osgDB::ReaderWriter* readerWriter = osgDB::Registry::instance()->getReaderWriterForExtension("gdal"); @@ -710,7 +715,10 @@ bool createWorld(const std::string& inputFile, const std::string& baseName, unsi bool doBumpMapping = true; - int bumpMapSize = 512; + int bumpMapSizeWidth = 4097; + int bumpMapSizeHeight = 4097; +// int bumpMapSizeWidth = 512; +// int bumpMapSizeHeight = 512; if (doBumpMapping) { @@ -727,28 +735,63 @@ bool createWorld(const std::string& inputFile, const std::string& baseName, unsi options->_sourceRatioWindow.set(0,0,1,1); options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW; - options->_destinationPixelWindow.set(0,0,512,512); + options->_destinationPixelWindow.set(0,0,bumpMapSizeWidth,bumpMapSizeHeight); osgDB::Registry::instance()->setOptions(options.get()); - osg::Image* image = osgDB::readImageFile(inputFile.c_str()); - if (image) - { - osg::HeightField* grid = createHeightField(image,osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(1.0,1.0,VERTICAL_SIZE)); - normalMap = createNormalMap(grid); - normalMap->setFileName("normalmap.rgb"); - osgDB::writeImageFile(*normalMap,"normalmap.rgb"); + + bool useImage = false; + if (useImage) + { + osg::Image* image = osgDB::readImageFile(inputFile.c_str()); + if (image) + { + osg::HeightField* grid = createHeightField(image,osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(1.0,1.0,VERTICAL_SIZE)); + normalMap = createNormalMap(grid); + normalMap->setFileName("normalmap.rgb"); + osgDB::writeImageFile(*normalMap,"normalmap.rgb"); - scene = createQuadTree(grid, - 0, grid->getNumColumns()-1, - 0, grid->getNumRows()-1, - 0.0f, 1.0f, - 0.0f, 1.0f, - 2000); +// scene = createQuadTree(grid, +// 0, grid->getNumColumns()-1, +// 0, grid->getNumRows()-1, +// 0.0f, 1.0f, +// 0.0f, 1.0f, +// 2000, numLevels); + + + } } - + else + { + osg::HeightField* grid = osgDB::readHeightFieldFile(inputFile.c_str()); + if (grid) + { + osg::HeightField::HeightList& hlist = grid->getHeightList(); + for(osg::HeightField::HeightList::iterator itr=hlist.begin(); + itr!=hlist.end(); + ++itr) + { + (*itr) *= VERTICAL_SIZE; + } + + normalMap = createNormalMap(grid); + normalMap->setFileName("normalmap.rgb"); + osgDB::writeImageFile(*normalMap,"normalmap.rgb"); +// osg::Geode* geode = new osg::Geode; +// geode->addDrawable(new osg::ShapeDrawable(grid)); +// +// scene = geode; + scene = createQuadTree(grid, + 0, grid->getNumColumns()-1, + 0, grid->getNumRows()-1, + 0.0f, 1.0f, + 0.0f, 1.0f, + 2000, numLevels); + + } + } } // generate diffuse map @@ -771,7 +814,10 @@ bool createWorld(const std::string& inputFile, const std::string& baseName, unsi // // } - diffuseMap = osgDB::readImageFile("LlanoTex.jpg"); + //diffuseMap = osgDB::readImageFile(diffuseTextureName.c_str()); + diffuseMap = new osg::Image; + diffuseMap->setFileName(diffuseTextureName.c_str()); + osg::Texture2D* diffuseMapTexture = new osg::Texture2D(diffuseMap); @@ -782,6 +828,7 @@ bool createWorld(const std::string& inputFile, const std::string& baseName, unsi bumpMap->setLightNumber(0); bumpMap->setNormalMapTextureUnit(0); bumpMap->setDiffuseTextureUnit(1); + bumpMap->selectTechnique(1); bumpMap->setOverrideDiffuseTexture(diffuseMapTexture); bumpMap->setOverrideNormalMapTexture(normalMapTexture); @@ -848,6 +895,9 @@ int main( int argc, char **argv ) while (arguments.read("-v",VERTICAL_SIZE)) {} + std::string diffuseTextureName("lz.ive"); + while (arguments.read("-t",diffuseTextureName)) {} + // if user request help write it out to cout. if (arguments.read("-h") || arguments.read("--help")) { @@ -876,7 +926,7 @@ int main( int argc, char **argv ) // create a graphics context to allow us to use OpenGL to compress textures. GraphicsContext gfx; - createWorld(inputFile,basename,(unsigned int)numLevels); + createWorld(inputFile,basename,diffuseTextureName,(unsigned int)numLevels); return 0; } diff --git a/include/osg/Shape b/include/osg/Shape index 3001255af..34b65fb35 100644 --- a/include/osg/Shape +++ b/include/osg/Shape @@ -436,7 +436,12 @@ class SG_EXPORT HeightField : public Shape META_Shape(osg, HeightField) - void allocateGrid(unsigned int numColumns,unsigned int numRows); + typedef std::vector HeightList; + + void allocate(unsigned int numColumns,unsigned int numRows); + + // deprecated. + void allocateGrid(unsigned int numColumns,unsigned int numRows) { allocate(numColumns,numRows); } inline unsigned int getNumColumns() const { return _columns; } inline unsigned int getNumRows() const { return _rows; } @@ -466,6 +471,9 @@ class SG_EXPORT HeightField : public Shape return _heights[c+r*_columns]; } + HeightList& getHeightList() { return _heights; } + const HeightList& getHeightList() const { return _heights; } + Vec3 getNormal(unsigned int c,unsigned int r) const; inline void setRotation(const Quat& quat) { _rotation = quat; } @@ -484,15 +492,17 @@ class SG_EXPORT HeightField : public Shape float _dy; Quat _rotation; - - typedef std::vector HeightList; HeightList _heights; }; +typedef HeightField Grid; + class CompositeShape : public Shape { public: + + typedef std::vector< ref_ptr > ChildList; diff --git a/include/osgDB/ReadFile b/include/osgDB/ReadFile index 8cb895691..a44f711a6 100644 --- a/include/osgDB/ReadFile +++ b/include/osgDB/ReadFile @@ -67,6 +67,26 @@ inline osg::Image* readImageFile(const std::string& filename) return readImageFile(filename,Registry::instance()->getUseObjectCacheHint()); } +/** Read an osg::HeightField from file. + * Return valid osg::HeightField on success, + * return NULL on failure. + * Use the useObjectCache flag to override the osgDB::Regisytr::getUseObjectCacheHint(). + * The osgDB::Registry is used to load the appropriate ReaderWriter plugin + * for the filename extension, and this plugin then handles the request + * to read the specified file.*/ +extern OSGDB_EXPORT osg::HeightField* readHeightFieldFile(const std::string& filename,bool useObjectCache); + +/** Read an osg::HeightField from file. + * Return valid osg::HeightField on success, + * return NULL on failure. + * The osgDB::Registry is used to load the appropriate ReaderWriter plugin + * for the filename extension, and this plugin then handles the request + * to read the specified file.*/ +inline osg::HeightField* readHeightFieldFile(const std::string& filename) +{ + return readHeightFieldFile(filename,Registry::instance()->getUseObjectCacheHint()); +} + /** Read an osg::Node from file. * Return valid osg::Node on success, * return NULL on failure. diff --git a/include/osgDB/ReaderWriter b/include/osgDB/ReaderWriter index c3a70726a..057b4f022 100644 --- a/include/osgDB/ReaderWriter +++ b/include/osgDB/ReaderWriter @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -73,14 +74,17 @@ class OSGDB_EXPORT ReaderWriter : public osg::Referenced osg::Object* getObject() { return _object.get(); } osg::Image* getImage() { return dynamic_cast(_object.get()); } + osg::HeightField* getHeightField() { return dynamic_cast(_object.get()); } osg::Node* getNode() { return dynamic_cast(_object.get()); } bool validObject() { return _object.valid(); } bool validImage() { return getImage()!=0; } + bool validHeightField() { return getHeightField()!=0; } bool validNode() { return getNode()!=0; } osg::Object* takeObject() { osg::Object* obj = _object.get(); if (obj) { obj->ref(); _object=NULL; obj->unref_nodelete(); } return obj; } osg::Image* takeImage() { osg::Image* image=dynamic_cast(_object.get()); if (image) { image->ref(); _object=NULL; image->unref_nodelete(); } return image; } + osg::HeightField* takeHeightField() { osg::HeightField* hf=dynamic_cast(_object.get()); if (hf) { hf->ref(); _object=NULL; hf->unref_nodelete(); } return hf; } osg::Node* takeNode() { osg::Node* node=dynamic_cast(_object.get()); if (node) { node->ref(); _object=NULL; node->unref_nodelete(); } return node; } const std::string& message() const { return _message; } @@ -129,18 +133,22 @@ class OSGDB_EXPORT ReaderWriter : public osg::Referenced virtual ReadResult readObject(const std::string& /*fileName*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } virtual ReadResult readImage(const std::string& /*fileName*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } + virtual ReadResult readHeightField(const std::string& /*fileName*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } virtual ReadResult readNode(const std::string& /*fileName*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } virtual WriteResult writeObject(const osg::Object& /*obj*/,const std::string& /*fileName*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); } virtual WriteResult writeImage(const osg::Image& /*image*/,const std::string& /*fileName*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); } + virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,const std::string& /*fileName*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); } virtual WriteResult writeNode(const osg::Node& /*node*/,const std::string& /*fileName*/,const Options* =NULL) { return WriteResult(WriteResult::FILE_NOT_HANDLED); } virtual ReadResult readObject(std::istream& /*fin*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } virtual ReadResult readImage(std::istream& /*fin*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } + virtual ReadResult readHeightField(std::istream& /*fin*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } virtual ReadResult readNode(std::istream& /*fin*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } virtual WriteResult writeObject(const osg::Object& /*obj*/,std::ostream& /*fout*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); } virtual WriteResult writeImage(const osg::Image& /*image*/,std::ostream& /*fout*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); } + virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,std::ostream& /*fout*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); } virtual WriteResult writeNode(const osg::Node& /*node*/,std::ostream& /*fout*/,const Options* =NULL) { return WriteResult(WriteResult::FILE_NOT_HANDLED); } diff --git a/include/osgDB/Registry b/include/osgDB/Registry index ca9a83594..28264e81f 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -120,6 +120,9 @@ class OSGDB_EXPORT Registry : public osg::Referenced ReaderWriter::ReadResult readImage(const std::string& fileName,bool useObjectCache); ReaderWriter::WriteResult writeImage(const osg::Image& obj, const std::string& fileName); + ReaderWriter::ReadResult readHeightField(const std::string& fileName,bool useObjectCache); + ReaderWriter::WriteResult writeHeightField(const osg::HeightField& obj, const std::string& fileName); + ReaderWriter::ReadResult readNode(const std::string& fileName,bool useObjectCache); ReaderWriter::WriteResult writeNode(const osg::Node& node, const std::string& fileName); @@ -231,6 +234,7 @@ class OSGDB_EXPORT Registry : public osg::Referenced ReaderWriter::ReadResult readObject(const std::string& fileName); ReaderWriter::ReadResult readImage(const std::string& fileName); + ReaderWriter::ReadResult readHeightField(const std::string& fileName); ReaderWriter::ReadResult readNode(const std::string& fileName); DotOsgWrapperMap _objectWrapperMap; diff --git a/include/osgDB/WriteFile b/include/osgDB/WriteFile index a937d6f2d..58f876dc3 100644 --- a/include/osgDB/WriteFile +++ b/include/osgDB/WriteFile @@ -15,6 +15,7 @@ #define OSGDB_WRITEFILE 1 #include +#include #include #include @@ -40,6 +41,14 @@ extern OSGDB_EXPORT bool writeObjectFile(const osg::Object& object, const std::s * to write the specified file.*/ extern OSGDB_EXPORT bool writeImageFile(const osg::Image& image, const std::string& filename); +/** Write an osg::HeightField to file. + * Return true on success, + * return false on failure. + * The osgDB::Registry is used to load the appropriate ReaderWriter plugin + * for the filename extension, and this plugin then handles the request + * to write the specified file.*/ +extern OSGDB_EXPORT bool writeHeightFieldFile(const osg::HeightField& hf, const std::string& filename); + /** Write an osg::Node to file. * Return true on success, * return false on failure. diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index 11f7923f6..3fb157896 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -765,7 +765,6 @@ void Geometry::drawImplementation(State& state) const unsigned int colorIndex = 0; unsigned int secondaryColorIndex = 0; unsigned int fogCoordIndex = 0; - unsigned int vertexAttribIndex = 0; #if USE_DEFAULT_NORMAL // if no values are defined for normal and color provide some defaults... diff --git a/src/osg/Shape.cpp b/src/osg/Shape.cpp index c47afe1a2..dcd03c82a 100644 --- a/src/osg/Shape.cpp +++ b/src/osg/Shape.cpp @@ -15,7 +15,7 @@ using namespace osg; -void HeightField::allocateGrid(unsigned int numColumns,unsigned int numRows) +void HeightField::allocate(unsigned int numColumns,unsigned int numRows) { if (_columns!=numColumns || _rows!=numRows) { diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index c27d2ee35..6a76a3115 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -266,11 +266,11 @@ void DatabasePager::run() //std::cout<<"In run loop"<tick(); + //osg::Timer_t t1 = osg::Timer::instance()->tick(); _fileRequestListEmptyBlock->block(); - osg::Timer_t t2 = osg::Timer::instance()->tick(); + //osg::Timer_t t2 = osg::Timer::instance()->tick(); _frameBlock->block(); - osg::Timer_t t3 = osg::Timer::instance()->tick(); + //osg::Timer_t t3 = osg::Timer::instance()->tick(); //std::cout<<"Time in _fileRequestListEmptyBlock block()"<delta_m(t1,t2)<delta_m(t2,t3)<readHeightField(filename,useObjectCache); + if (rr.validHeightField()) return rr.takeHeightField(); + if (rr.error()) notify(WARN) << rr.message() << std::endl; + return NULL; +} + + Node* osgDB::readNodeFile(const std::string& filename,bool useObjectCache) { ReaderWriter::ReadResult rr = Registry::instance()->readNode(filename,useObjectCache); diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 9845b9183..52ee52119 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -1383,6 +1383,151 @@ ReaderWriter::WriteResult Registry::writeImage(const Image& image,const std::str return results.front(); } +ReaderWriter::ReadResult Registry::readHeightField(const std::string& fileName) +{ + // record the existing reader writer. + std::set rwOriginal; + + // record the errors reported by readerwriters. + typedef std::vector Results; + Results results; + + // first attempt to load the file from existing ReaderWriter's + for(ReaderWriterList::iterator itr=_rwList.begin(); + itr!=_rwList.end(); + ++itr) + { + rwOriginal.insert(itr->get()); + ReaderWriter::ReadResult rr = (*itr)->readHeightField(fileName,_options.get()); + if (rr.validHeightField()) return rr; + else if (rr.error()) results.push_back(rr); + } + + // now look for a plug-in to load the file. + std::string libraryName = createLibraryNameForFile(fileName); + if (loadLibrary(libraryName)) + { + for(ReaderWriterList::iterator itr=_rwList.begin(); + itr!=_rwList.end(); + ++itr) + { + if (rwOriginal.find(itr->get())==rwOriginal.end()) + { + ReaderWriter::ReadResult rr = (*itr)->readHeightField(fileName,_options.get()); + if (rr.validHeightField()) return rr; + else if (rr.error()) results.push_back(rr); + } + } + } + + if (results.empty()) + { + return ReaderWriter::ReadResult("Warning: Could not find plugin to read HeightField from file \""+fileName+"\"."); + } + + return results.front(); +} + + +ReaderWriter::ReadResult Registry::readHeightField(const std::string& fileName,bool useObjectCache) +{ + std::string file = findDataFile( fileName ); + if (file.empty()) + file = fileName; +// return ReaderWriter::ReadResult("Warning: file \""+fileName+"\" not found."); + + if (useObjectCache) + { + // search for entry in the object cache. + ObjectCache::iterator oitr=_objectCache.find(file); + if (oitr!=_objectCache.end()) + { + notify(INFO)<< "returning cached instanced of "<(oitr->second.first.get()); + if (HeightField) return HeightField; + else return ReaderWriter::ReadResult("Error file not of type osg::HeightField"); + } + + PushAndPopDataPath tmpfile(getFilePath(file)); + + ReaderWriter::ReadResult rr = readHeightField(file); + if (rr.validHeightField()) + { + // update cache with new entry. + notify(INFO)<<"Adding to cache HeightField "< rwOriginal; + + // record the errors reported by readerwriters. + typedef std::vector Results; + Results results; + + // first attempt to load the file from existing ReaderWriter's + for(ReaderWriterList::iterator itr=_rwList.begin(); + itr!=_rwList.end(); + ++itr) + { + rwOriginal.insert(itr->get()); + ReaderWriter::WriteResult rr = (*itr)->writeHeightField(HeightField,fileName,_options.get()); + if (rr.success()) return rr; + else if (rr.error()) results.push_back(rr); + } + + // now look for a plug-in to save the file. + std::string libraryName = createLibraryNameForFile(fileName); + if (loadLibrary(libraryName)) + { + for(ReaderWriterList::iterator itr=_rwList.begin(); + itr!=_rwList.end(); + ++itr) + { + if (rwOriginal.find(itr->get())==rwOriginal.end()) + { + ReaderWriter::WriteResult rr = (*itr)->writeHeightField(HeightField,fileName,_options.get()); + if (rr.success()) return rr; + else if (rr.error()) results.push_back(rr); + } + } + } + + if (results.empty()) + { + return ReaderWriter::WriteResult("Warning: Could not find plugin to write HeightField to file \""+fileName+"\"."); + } + + return results.front(); +} + + ReaderWriter::ReadResult Registry::readNode(const std::string& fileName) { diff --git a/src/osgDB/WriteFile.cpp b/src/osgDB/WriteFile.cpp index a5c59f6c0..9b23d0180 100644 --- a/src/osgDB/WriteFile.cpp +++ b/src/osgDB/WriteFile.cpp @@ -40,6 +40,13 @@ bool osgDB::writeImageFile(const Image& image,const std::string& filename) } +bool osgDB::writeHeightFieldFile(const HeightField& HeightField,const std::string& filename) +{ + ReaderWriter::WriteResult wr = Registry::instance()->writeHeightField(HeightField,filename); + if (wr.error()) notify(WARN) << wr.message() << std::endl; + return wr.success(); +} + bool osgDB::writeNodeFile(const Node& node,const std::string& filename) { ReaderWriter::WriteResult wr = Registry::instance()->writeNode(node,filename); diff --git a/src/osgFX/BumpMapping.cpp b/src/osgFX/BumpMapping.cpp index 74a158392..50f700eae 100644 --- a/src/osgFX/BumpMapping.cpp +++ b/src/osgFX/BumpMapping.cpp @@ -504,6 +504,8 @@ namespace } // second pass, self-shadowing + bool selfShadowing = false; + if (selfShadowing) { std::ostringstream vp_oss; vp_oss << diff --git a/src/osgPlugins/gdal/GNUmakefile b/src/osgPlugins/gdal/GNUmakefile index 356570cdc..0fb81e830 100644 --- a/src/osgPlugins/gdal/GNUmakefile +++ b/src/osgPlugins/gdal/GNUmakefile @@ -4,7 +4,7 @@ include $(TOPDIR)/Make/makedefs CXXFILES =\ ReaderWriterGDAL.cpp\ -LIBS += $(OSG_LIBS) -lgdal.1.1 $(OTHER_LIBS) +LIBS += $(OSG_LIBS) -lgdal $(OTHER_LIBS) TARGET_BASENAME = gdal diff --git a/src/osgPlugins/gdal/ReaderWriterGDAL.cpp b/src/osgPlugins/gdal/ReaderWriterGDAL.cpp index 93009e6f6..28c992f4d 100644 --- a/src/osgPlugins/gdal/ReaderWriterGDAL.cpp +++ b/src/osgPlugins/gdal/ReaderWriterGDAL.cpp @@ -145,6 +145,13 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter GDALRasterBand* bandBlue = 0; GDALRasterBand* bandAlpha = 0; + int internalFormat = GL_LUMINANCE; + unsigned int pixelFormat = GL_LUMINANCE; + unsigned int dataType = 0; + unsigned int numBytesPerPixel = 0; + + GDALDataType targetGDALType = GDT_Byte; + for(int b=1;b<=numBands;++b) { @@ -177,6 +184,22 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter // // std::cout << " min "<GetRasterDataType(); + switch(band->GetRasterDataType()) + { + case(GDT_Byte): dataType = GL_UNSIGNED_BYTE; numBytesPerPixel = 1; break; + case(GDT_UInt16): dataType = GL_UNSIGNED_SHORT; numBytesPerPixel = 2; break; + case(GDT_Int16): dataType = GL_SHORT; numBytesPerPixel = 2; break; + case(GDT_UInt32): dataType = GL_UNSIGNED_INT; numBytesPerPixel = 4; break; + case(GDT_Int32): dataType = GL_INT; numBytesPerPixel = 4; break; + case(GDT_Float32): dataType = GL_FLOAT; numBytesPerPixel = 4; break; + case(GDT_Float64): dataType = GL_DOUBLE; numBytesPerPixel = 8; break; // not handled + default: dataType = 0; numBytesPerPixel = 0; break; // not handled + } + } } @@ -184,9 +207,13 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter int t = destHeight; int r = 1; - int internalFormat = GL_LUMINANCE; - unsigned int pixelFormat = GL_LUMINANCE; - unsigned int dataType = GL_FLOAT; + + if (dataType==0) + { + dataType = GL_UNSIGNED_BYTE; + numBytesPerPixel = 1; + targetGDALType = GDT_Byte; + } unsigned char* imageData = 0; @@ -196,39 +223,37 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter { // RGBA - int pixelSpace=4; + int pixelSpace=4*numBytesPerPixel; int lineSpace=destWidth * pixelSpace; imageData = new unsigned char[destWidth * destHeight * pixelSpace]; pixelFormat = GL_RGBA; internalFormat = GL_RGBA; - dataType = GL_UNSIGNED_BYTE; std::cout << "reading RGBA"<RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); - bandGreen->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); - bandBlue->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+2),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); - bandAlpha->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+3),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); + bandRed->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); + bandGreen->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); + bandBlue->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+2),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); + bandAlpha->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+3),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); } else { // RGB - int pixelSpace=3; + int pixelSpace=3*numBytesPerPixel; int lineSpace=destWidth * pixelSpace; imageData = new unsigned char[destWidth * destHeight * pixelSpace]; pixelFormat = GL_RGB; internalFormat = GL_RGB; - dataType = GL_UNSIGNED_BYTE; std::cout << "reading RGB"<RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); - bandGreen->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); - bandBlue->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+2),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); + bandRed->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); + bandGreen->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); + bandBlue->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+2),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); } } else if (bandGray) @@ -236,48 +261,45 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter if (bandAlpha) { // Luminance alpha - int pixelSpace=2; + int pixelSpace=2*numBytesPerPixel; int lineSpace=destWidth * pixelSpace; imageData = new unsigned char[destWidth * destHeight * pixelSpace]; pixelFormat = GL_LUMINANCE_ALPHA; internalFormat = GL_LUMINANCE_ALPHA; - dataType = GL_UNSIGNED_BYTE; std::cout << "reading grey + alpha"<RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); - bandAlpha->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); + bandGray->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); + bandAlpha->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); } else { // Luminance map - int pixelSpace=1; + int pixelSpace=1*numBytesPerPixel; int lineSpace=destWidth * pixelSpace; imageData = new unsigned char[destWidth * destHeight * pixelSpace]; pixelFormat = GL_LUMINANCE; internalFormat = GL_LUMINANCE; - dataType = GL_UNSIGNED_BYTE; std::cout << "reading grey"<RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); + bandGray->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); } } else if (bandAlpha) { - // alpha map (treat as a Luminance map) - int pixelSpace=1; + // alpha map + int pixelSpace=1*numBytesPerPixel; int lineSpace=destWidth * pixelSpace; imageData = new unsigned char[destWidth * destHeight * pixelSpace]; - pixelFormat = GL_LUMINANCE; - internalFormat = GL_LUMINANCE; - dataType = GL_UNSIGNED_BYTE; + pixelFormat = GL_ALPHA; + internalFormat = GL_ALPHA; std::cout << "reading alpha"<RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,GDT_Byte,pixelSpace,lineSpace); + bandAlpha->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); } @@ -312,6 +334,215 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter } + virtual ReadResult readHeightField(const std::string& fileName, const osgDB::ReaderWriter::Options* options) + { + //std::string ext = osgDB::getFileExtension(fileName); + //if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + initGDAL(); + + std::auto_ptr dataset((GDALDataset*)GDALOpen(fileName.c_str(),GA_ReadOnly)); + if (!dataset.get()) return ReadResult::FILE_NOT_HANDLED; + + int dataWidth = dataset->GetRasterXSize(); + int dataHeight = dataset->GetRasterYSize(); + + int windowX = 0; + int windowY = 0; + int windowWidth = dataWidth; + int windowHeight = dataHeight; + + int destX = 0; + int destY = 0; + int destWidth = osg::minimum(dataWidth,1024); + int destHeight = osg::minimum(dataHeight,1024); + + osgDB::ImageOptions::TexCoordRange* texCoordRange = 0; + + const osgDB::ImageOptions* imageOptions = dynamic_cast(options); + if (imageOptions) + { + std::cout<<"Got ImageOptions"<_sourceImageWindowMode) + { + case(osgDB::ImageOptions::RATIO_WINDOW): + { + double desiredX = (double)dataWidth * imageOptions->_sourceRatioWindow.windowX; + double desiredY = (double)dataHeight * imageOptions->_sourceRatioWindow.windowY; + double desiredWidth = (double)dataWidth * imageOptions->_sourceRatioWindow.windowWidth; + double desiredHeight = (double)dataHeight * imageOptions->_sourceRatioWindow.windowHeight; + + windowX = osg::maximum((int)(floor(desiredX))-margin,0); + windowY = osg::maximum((int)(floor(desiredY))-margin,0); + windowWidth = osg::minimum((int)(ceil(desiredX + desiredWidth))+margin,dataWidth)-windowX; + windowHeight = osg::minimum((int)(ceil(desiredY + desiredHeight))+margin,dataHeight)-windowY; + + texCoordRange = new osgDB::ImageOptions::TexCoordRange; + texCoordRange->set((desiredX-(double)windowX)/(double)windowWidth, + ((double)(windowY+windowHeight) -(desiredY+desiredHeight))/(double)windowHeight, + (desiredWidth)/(double)windowWidth, + (desiredHeight)/(double)windowHeight); + std::cout<<"tex coord range "<_x<<" "<_y<<" "<_w<<" "<_h<_sourcePixelWindow.windowX; + windowY = imageOptions->_sourcePixelWindow.windowY; + windowWidth = imageOptions->_sourcePixelWindow.windowWidth; + windowHeight = imageOptions->_sourcePixelWindow.windowHeight; + break; + default: + // leave source window dimensions as whole image. + break; + } + + switch(imageOptions->_destinationImageWindowMode) + { + case(osgDB::ImageOptions::RATIO_WINDOW): + destX = (unsigned int)(floor((double)dataWidth * imageOptions->_destinationRatioWindow.windowX)); + destY = (unsigned int)(floor((double)dataHeight * imageOptions->_destinationRatioWindow.windowY)); + destWidth = (unsigned int)(ceil((double)dataWidth * (imageOptions->_destinationRatioWindow.windowX + imageOptions->_destinationRatioWindow.windowWidth)))-windowX; + destHeight = (unsigned int)(ceil((double)dataHeight * (imageOptions->_destinationRatioWindow.windowY + imageOptions->_destinationRatioWindow.windowHeight)))-windowY; + break; + case(osgDB::ImageOptions::PIXEL_WINDOW): + destX = imageOptions->_destinationPixelWindow.windowX; + destY = imageOptions->_destinationPixelWindow.windowY; + destWidth = imageOptions->_destinationPixelWindow.windowWidth; + destHeight = imageOptions->_destinationPixelWindow.windowHeight; + break; + default: + // leave source window dimensions as whole image. + break; + } + + } + +// windowX = 0; +// windowY = 0; +// windowWidth = destWidth; +// windowHeight = destHeight; + + std::cout << " windowX = "<GetRasterCount()<GetProjectionRef()<GetGeoTransform(geoTransform)!=CE_None) + { + std::cout << " GetGeoTransform "<< std::endl; + std::cout << " Origin = "<GetRasterCount(); + + + GDALRasterBand* bandGray = 0; + GDALRasterBand* bandRed = 0; + GDALRasterBand* bandGreen = 0; + GDALRasterBand* bandBlue = 0; + GDALRasterBand* bandAlpha = 0; + + for(int b=1;b<=numBands;++b) + { + + GDALRasterBand* band = dataset->GetRasterBand(b); + + std::cout << " Band "<allocate(destWidth,destHeight); + + bandSelected->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(&(hf->getHeightList().front())),destWidth,destHeight,GDT_Float32,0,0); + + +// unsigned short* data = new unsigned short[destWidth*destHeight]; +// bandSelected->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)data,destWidth,destHeight,GDT_UInt16,0,0); +// +// // copy ushorts across. +// for(unsigned int r=0;rgetNumRows();++r) +// { +// for(unsigned int c=0;cgetNumColumns();++c) +// { +// hf->setHeight(c,r,*data); +// ++data; +// } +// } + + // now need to flip since the OSG's origin is in lower left corner. + std::cout<<"flipping"<getNumRows()-1; + for(unsigned int r=0;rgetNumColumns();++c) + { + float temp = hf->getHeight(c,r); + hf->setHeight(c,r,hf->getHeight(c,copy_r)); + hf->setHeight(c,copy_r,temp); + } + } + + return hf; + } + + return ReadResult::FILE_NOT_HANDLED; + + } + void initGDAL() { static bool s_initialized = false;