diff --git a/Make/makedirdefs b/Make/makedirdefs index 6c601810c..2756ea14c 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -128,6 +128,7 @@ EXAMPLE_DIRS = \ osgautotransform\ osgbillboard\ osgbluemarble\ + osgdem\ osgcallback\ osgcameragroup\ osgclip\ diff --git a/doc/stereo.html b/doc/stereo.html index 78d977bce..993932335 100644 --- a/doc/stereo.html +++ b/doc/stereo.html @@ -1,306 +1,228 @@ - + - - - Native stereo support + + + Native stereo support - - + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
IndexIntroductionContentsInstallDependenciesexamplesDataViewerStereoPlanReference Guides
IndexIntroductionContentsInstallDependenciesexamplesDataViewerStereoPlanReference Guides
- -

-Native Support for Stereo

-The OSG has support for anaglyphic stereo (i.e. red/green or red/cyan glasses), -quad buffered stereo (i.e. active stereo using shutter glasses, or passive -stereo using polarized projectors & glasses) and horizontal and vertical -split window stereo implementations. Almost all OSG applications have the -potential for stereo support simply by setting the relevant environmental -variables, or via command line arguments. Little or no code changes will -be required, the support is handled transparently inside osgUtil::SceneView's -handling of rendering. It is a simple as: -
    osgviewer --stereo cow.osg -

If the user is planning to use head tracked stereo, or a cave then it -is currently recommend to set it up via a VR toolkit such as VRjuggler, -in this case refer to the VR toolkits handling of stereo, and keep all -the OSG's stereo specific environment variables (below) set to OFF, or -set the values to off within own your own applications. -
+

Native Support for Stereo

+The OSG has support for anaglyphic stereo (i.e. red/green or red/cyan +glasses), quad buffered stereo (i.e. active stereo using shutter +glasses, or passive stereo using polarized projectors & glasses) +and horizontal and vertical split window stereo implementations. Almost +all OSG applications have the potential for stereo support simply by +setting the relevant environmental variables, or via command line +arguments. Little or no code changes will be required, the support is +handled transparently inside osgUtil::SceneView's handling of +rendering. It is a simple as:
+    osgviewer --stereo cow.osg +

If the user is planning to use head tracked stereo, or a cave then +it is currently recommend to set it up via a VR toolkit such as +VRjuggler, in this case refer to the VR toolkits handling of stereo, +and keep all the OSG's stereo specific environment variables (below) +set to OFF, or set the values to off within own your own applications.
+


-

-The environmental variables of interest:

- +

The environmental variables of interest:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OSG_STEREOONTurn stereo on 
OFFTurn stereo off (default). 
OSG_STEREO_MODEANAGLYPHICUse anaglyphic stereo when in stereo (default). 
QUAD_BUFFERUse quad buffered stereo when in stereo. 
HORIZONTAL_SPLITUse horizontal split stereo mode when in stereo 
VERTICAL_SPLITUse vertical split stereo mode when in stereo 
OSG_SCREEN_DISTANCE0.50Set the distance the viewer is from screen in metres (default shown) 
OSG_SCREEN_HEIGHT0.26Set the height if image on the screen in metres (default shown) 
OSG_EYE_SEPARATION0.06Set the eye separation - interoccular distance (default shown.) 
OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION42Set the number of pixels between the left and right viewports (default -shown).
OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPINGLEFT_EYE_LEFT_VIEWPORTSet the left eye to render to left viewport, right eye to right viewport -(default). 
LEFT_EYE_RIGHT_VIEWPORTSet the left eye to render to right viewport, right eye to left viewport. 
OSG_SPLIT_STEREO_VERTICAL_SEPARATION42Set the number of pixels between the top and bottom viewports (default -shown).
OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPINGLEFT_EYE_TOP_VIEWPORTSet the left eye to render to top viewport, right eye to bottom viewport -(default). 
LEFT_EYE_BOTTOM_VIEWPORTSet the left eye to render to bottom viewport, right eye to top viewport. 
OSG_STEREOONTurn stereo on 

+
OFFTurn stereo off (default). 
OSG_STEREO_MODEANAGLYPHICUse anaglyphic stereo when in stereo (default). 

+
QUAD_BUFFERUse quad buffered stereo when in stereo. 

+
HORIZONTAL_SPLITUse horizontal split stereo mode when in stereo 

+
VERTICAL_SPLITUse vertical split stereo mode when in stereo 
OSG_SCREEN_DISTANCE0.50Set the distance the viewer is from screen in metres (default +shown) 
OSG_SCREEN_HEIGHT0.26Set the height if image on the screen in metres (default +shown) 
OSG_EYE_SEPARATION0.06Set the eye separation - interoccular distance (default +shown.) 
OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION42Set the number of pixels between the left and right viewports +(default shown).
OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPINGLEFT_EYE_LEFT_VIEWPORTSet the left eye to render to left viewport, right eye to +right viewport (default). 

+
LEFT_EYE_RIGHT_VIEWPORTSet the left eye to render to right viewport, right eye to +left viewport. 
OSG_SPLIT_STEREO_VERTICAL_SEPARATION42Set the number of pixels between the top and bottom viewports +(default shown).
OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPINGLEFT_EYE_TOP_VIEWPORTSet the left eye to render to top viewport, right eye to +bottom viewport (default). 

+
LEFT_EYE_BOTTOM_VIEWPORTSet the left eye to render to bottom viewport, right eye to +top viewport. 
-
-

-Command line arguments can be used to override these settings:

- +

Command line arguments can be used to override these settings:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-stereoSwitch on stereo. 
-stereoONSwitch on stereo. 
OFFSwitch off stereo. 
ANAGLYPHICSwitch on ANAGLYPHIC stereo. 
QUAD_BUFFERSwitch on QUAD_BUFFER stereo. 
VERTICAL_SPLITSwitch on VERTICAL_SPLIT stereo. 
HORIZONTAL_SPLITSwitch on VERTICAL_SPLIT stereo. 
-stereo
+
Switch on stereo. 
-stereoONSwitch on stereo. 

+
OFFSwitch off stereo. 

+
ANAGLYPHICSwitch on ANAGLYPHIC stereo. 

+
QUAD_BUFFERSwitch on QUAD_BUFFER stereo. 

+
VERTICAL_SPLITSwitch on VERTICAL_SPLIT stereo. 

+
HORIZONTAL_SPLITSwitch on VERTICAL_SPLIT stereo. 
-
-

-Examples:

-To invoke stereo from the comandline: -
    osgviewer -stereo cow.osg -

To invoke quad buffered stereo from the commandline: -
    osgviewer -stereo QUAD_BUFFER cow.osg -

To force all apps to start up in quad buffered stereo (if system supports -it) -
    export OSG_STEREO=ON -
    export OSG_STEREO_MODE=QUAD_BUFFER -
    osgviewer cow.osg +

Examples:

+To invoke stereo from the comandline:
+    osgviewer -stereo cow.osg +

To invoke quad buffered stereo from the commandline:
+    osgviewer -stereo QUAD_BUFFER cow.osg

+

To force all apps to start up in quad buffered stereo (if system +supports it)
+    export OSG_STEREO=ON
+    export OSG_STEREO_MODE=QUAD_BUFFER
+    osgviewer cow.osg

To set quad buffered stereo to the default, but use the commandline -to switch stereo on: -
    export OSG_STEREO=OFF -
    export OSG_STEREO_MODE=QUAD_BUFFER -
    osgviewer -stereo cow.osg -

+to switch stereo on:
+    export OSG_STEREO=OFF
+    export OSG_STEREO_MODE=QUAD_BUFFER
+    osgviewer -stereo cow.osg

+


-

-Size matters:

+

Size matters:

For appropriate depth perception the stereo code creates separate left and eye views, both the frustum and modelview are shifted to account for the separate eye views.  To achieve the right amount of adjustment the OSG requires the users eye separation, the distance from the eyes to -the screen and the height of the screen.  The OSG will use the defaults -of 0.05m,0.5m and 0.26m respectively which are assumed to be reasonable -defaults for most users workstation configurations, note the OSG_SCREEN_HEIGHT -is the image height rather than total size of your monitor/display surface.  -For the best stereo effects please measure these values and set them up -via the environmental variables.  Once set the views you get should -give improved depth perception.  A good way of measuring how well -you are configured for your display is to fly away from objects (using -the FlightManipulator for instance, but not the TrackballManipulator, see +the screen and the height of the screen.  The OSG will use the +defaults of 0.05m,0.5m and 0.26m respectively which are assumed to be +reasonable defaults for most users workstation configurations, note the +OSG_SCREEN_HEIGHT is the image height rather than total size of your +monitor/display surface.  For the best stereo effects please +measure these values and set them up via the environmental +variables.  Once set the views you get should give improved depth +perception.  A good way of measuring how well you are configured +for your display is to fly away from objects (using the +FlightManipulator for instance, but not the TrackballManipulator, see below) so that they go of toward infinity. As they move away the offset between the two images should tend towards your eye separation, if you -achieve this then the object will be perceived as at infinity. +achieve this then the object will be perceived as at infinity.

-
-

-Camera Manipulator Modes:

-There are three osgUtil::CameraManipulator's which come with osgUtil, which -operate as a Trackball, Drive and Flight modes of interaction (see osgviewer.html -for how to invoke them in the scene graph viewer). The osgUtil::Trackball -Manipulator automatically scales the fusion distance to that which will -fusion on center point of rotation - this will appear at the middle of -the monitor at the monitors depth. Whereas, the osgUtil::DriveManipualtor, -osgUtil::FlightManipulator scale the fusion distance to the distance the -viewer is from the screen, the results in a perception that the virtual -world is scaled to physical world, this is clearly better for simulators -and alike. You can control the fusion of the image in these two modes via -the osg::Camera::setFusionDistanceMode(FusionDistanceMode mode) where mode -can be osg::Camera::PROPORTIONAL_TO_LOOK_DISTANCE (used by Trackball) or -osg::Camera::PROPORTIONAL_TO_SCREEN_DISTANCE (used by Drive and Flight), -and osg::Camera::setFusionDistanceRatio(float). See include/osg/Camera -for further details, and the camera manipulators for implementation details. -The fusion distance ratio defaults to 1.0 but can be biased to move objects -out or into screen, they will also appear to get smaller and larger respectively. -The camera manipulators allow the user to alter this value at runtime via -the '+' and '-' keys. diff --git a/examples/osgbluemarble/osgbluemarble.cpp b/examples/osgbluemarble/osgbluemarble.cpp index 7616d47f3..4cfe88c2b 100644 --- a/examples/osgbluemarble/osgbluemarble.cpp +++ b/examples/osgbluemarble/osgbluemarble.cpp @@ -69,10 +69,14 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW; options->_destinationPixelWindow.set(0,0,256,256); + osgDB::ImageOptions::TexCoordRange* texCoordRange = 0; + osgDB::Registry::instance()->setOptions(options.get()); osg::Image* image = osgDB::readImageFile(filename.c_str()); if (image) { + texCoordRange = dynamic_cast(image->getUserData()); + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP); @@ -82,16 +86,18 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x texture->setMaxAnisotropy(8); stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON); - texture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT3_COMPRESSION); - - osg::ref_ptr state = new osg::State; - texture->apply(*state); - - image->readImageFromCurrentTexture(); - - texture->setInternalFormatMode(osg::Texture::USE_IMAGE_DATA_FORMAT); - - std::cout<<"glGetError()=="<setInternalFormatMode(osg::Texture::USE_S3TC_DXT3_COMPRESSION); + + osg::ref_ptr state = new osg::State; + texture->apply(*state); + + image->readImageFromCurrentTexture(); + + texture->setInternalFormatMode(osg::Texture::USE_IMAGE_DATA_FORMAT); + } } @@ -114,9 +120,24 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x color[0].set(255,255,255,255); + + osg::Vec2 tex_orig(0.0f,0.0f); + float rowTexDelta = 1.0f/(float)(numRows-1); float columnTexDelta = 1.0f/(float)(numColumns-1); + if (texCoordRange) + { + tex_orig.set(texCoordRange->_x,texCoordRange->_y); + rowTexDelta = texCoordRange->_h/(float)(numRows-1); + columnTexDelta = texCoordRange->_w/(float)(numColumns-1); + + std::cout<<"setting tex values to use texCoordRange"<setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-i ","Specify the input file to process"); + arguments.getApplicationUsage()->addCommandLineOption("-o ","Specify the output master file to generate"); + arguments.getApplicationUsage()->addCommandLineOption("-l ","Specify the number of PagedLOD levels to generate"); arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + std::string inputFile; + while (arguments.read("-i",inputFile)) {} + + std::string basename("output.ive"); + while (arguments.read("-o",basename)) {} + + float numLevels; + while (arguments.read("-l",numLevels)) {} // if user request help write it out to cout. if (arguments.read("-h") || arguments.read("--help")) @@ -365,7 +399,6 @@ int main( int argc, char **argv ) std::string left_hemisphere("land_shallow_topo_west.tif"); std::string right_hemisphere("land_shallow_topo_east.tif"); - std::string basename("BlueMarble/bluemarble.ive"); // create a graphics context to allow us to use OpenGL to compress textures. GraphicsContext gfx; diff --git a/examples/osgdem/GNUmakefile b/examples/osgdem/GNUmakefile new file mode 100644 index 000000000..a6ae3e106 --- /dev/null +++ b/examples/osgdem/GNUmakefile @@ -0,0 +1,18 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgdem.cpp\ + +LIBS += -losgProducer -lProducer -losgFX -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgdem + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgdem/GNUmakefile.inst b/examples/osgdem/GNUmakefile.inst new file mode 100644 index 000000000..d27395804 --- /dev/null +++ b/examples/osgdem/GNUmakefile.inst @@ -0,0 +1,13 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgdem.cpp\ + +LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgdem + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgdem/osgdem.cpp b/examples/osgdem/osgdem.cpp new file mode 100644 index 000000000..bee5453cb --- /dev/null +++ b/examples/osgdem/osgdem.cpp @@ -0,0 +1,883 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commericial and non commericial applications, + * as long as this copyright notice is maintained. + * + * This application 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. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + + +float VERTICAL_SIZE = 0.0005; + +class GraphicsContext { + public: + GraphicsContext() + { + rs = new Producer::RenderSurface; + rs->setWindowRectangle(0,0,1,1); + rs->useBorder(false); + rs->useConfigEventThread(false); + rs->realize(); + std::cout<<"Realized window"< rs; +}; + +osg::Image* createNormalMap(osg::HeightField* grid) +{ + osg::Image* image = new osg::Image; + image->allocateImage(grid->getNumColumns(),grid->getNumRows(),1,GL_RGB,GL_BYTE); + + char* ptr = (char*) image->data(); + for(unsigned int r=0;rgetNumRows();++r) + { + for(unsigned int c=0;cgetNumColumns();++c) + { + osg::Vec3 normal = grid->getNormal(c,r); + (*ptr++) = (char)((normal.x()+1.0)*0.5*255); + (*ptr++) = (char)((normal.y()+1.0)*0.5*255); + (*ptr++) = (char)((normal.z()+1.0)*0.5*255); + } + } + + return image; + +} + + +template< typename T> +osg::HeightField* _createHeightField(osg::Image* image, float zScale) +{ + unsigned char* ptr = image->data(); + unsigned int rowSizeInBytes = image->getRowSizeInBytes(); + unsigned int pixelSizeInBits = image->getPixelSizeInBits(); + unsigned int pixelSizeInBytes = pixelSizeInBits/8; + + unsigned int numColumns = image->s(); + unsigned int numRows = image->t(); + + osg::HeightField* grid = new osg::HeightField; + grid->allocateGrid(numColumns,numRows); + + for(unsigned int r=0;rsetHeight(c,r,zScale*(float)(*((T*)ptr_in_row))); + ptr_in_row += pixelSizeInBytes; + } + ptr += rowSizeInBytes; + } + + return grid; +} + +osg::HeightField* createHeightField(osg::Image* image, const osg::Vec3& origin, const osg::Vec3& size) +{ + osg::HeightField* grid = new osg::HeightField; + switch(image->getDataType()) + { + case(GL_UNSIGNED_BYTE): grid = _createHeightField(image,size.z()); break; + case(GL_BYTE): grid = _createHeightField(image,size.z()); break; + case(GL_UNSIGNED_SHORT): grid = _createHeightField(image,size.z()); break; + case(GL_SHORT): grid = _createHeightField(image,size.z()); break; + case(GL_UNSIGNED_INT): grid = _createHeightField(image,size.z()); break; + case(GL_INT): grid = _createHeightField(image,size.z()); break; + case(GL_FLOAT): grid = _createHeightField(image,size.z()); break; + } + grid->setOrigin(origin); + grid->setXInterval(size.x()/(float)(image->s()-1)); + grid->setYInterval(size.y()/(float)(image->s()-1)); + + return grid; + +} + +osg::Node* createTile(osg::HeightField* grid, + unsigned int columnBegin, unsigned int columnEnd, + unsigned int rowBegin, unsigned int rowEnd, + float xTexCoordBegin, float xTexCoordEnd, + float yTexCoordBegin, float yTexCoordEnd, + unsigned int targetNumPolygonsPerTile) +{ + + + int numPolys = (columnEnd-columnBegin)*(rowEnd-rowBegin)*2; + int numColumns, numRows; + bool oneToOneMapping = numPolys<=targetNumPolygonsPerTile; + if (oneToOneMapping) + { + numColumns = (columnEnd-columnBegin)+1; + numRows = (rowEnd-rowBegin)+1; + } + else + { + numColumns = (int)sqrtf((float)targetNumPolygonsPerTile/2.0) + 1; + numRows = targetNumPolygonsPerTile/(2*(numColumns)-1) + 1; + } + + bool createSkirt = true; + + + int numVerticesInBody = numColumns*numRows; + int numVerticesInSkirt = createSkirt ? numColumns*2 + numRows*2 - 4 : 0; + int numVertices = numVerticesInBody+numVerticesInSkirt; + + osg::Vec3 skirtVector(0.0f,0.0f,-0.003f); + + + osg::Geometry* geometry = new osg::Geometry; + + osg::Vec3Array& v = *(new osg::Vec3Array(numVertices)); + osg::Vec2Array& t = *(new osg::Vec2Array(numVertices)); + osg::UByte4Array& color = *(new osg::UByte4Array(1)); + + color[0].set(255,255,255,255); + + + int vi=0; + int r,c; + if (!oneToOneMapping) + { + for(r=0;rgetOrigin()+osg::Vec3(grid->getXInterval()*(float)col, + grid->getYInterval()*(float)row, + grid->getHeight(col,row)); + t[vi].x() = xTexCoordBegin + (xTexCoordEnd-xTexCoordBegin)*(float)(col-columnBegin)/(float)(columnEnd-columnBegin); + t[vi].y() = yTexCoordBegin + (yTexCoordEnd-yTexCoordBegin)*(float)(row-rowBegin)/(float)(rowEnd-rowBegin); + + ++vi; + } + } + } + else + { + for(r=rowBegin;r<=rowEnd;++r) + { + for(c=columnBegin;c<=columnEnd;++c) + { + v[vi] = grid->getOrigin()+osg::Vec3(grid->getXInterval()*c, + grid->getYInterval()*r, + grid->getHeight(c,r)); + t[vi].x() = xTexCoordBegin + (xTexCoordEnd-xTexCoordBegin)*(float)(c-columnBegin)/(float)(columnEnd-columnBegin); + t[vi].y() = yTexCoordBegin + (yTexCoordEnd-yTexCoordBegin)*(float)(r-rowBegin)/(float)(rowEnd-rowBegin); + + ++vi; + } + } + } + + + + geometry->setVertexArray(&v); + geometry->setColorArray(&color); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + geometry->setTexCoordArray(0,&t); + geometry->setTexCoordArray(1,&t); + + bool pickOutDiagonals = true; + if (pickOutDiagonals) + { + osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_TRIANGLES,2*3*(numColumns-1)*(numRows-1))); + geometry->addPrimitiveSet(&drawElements); + int ei=0; + for(r=0;raddPrimitiveSet(&drawElements); + int ei=0; + for(c=0;c0) + { + osg::DrawElementsUShort& skirtDrawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numVerticesInSkirt+2)); + geometry->addPrimitiveSet(&skirtDrawElements); + int ei=0; + int firstSkirtVertexIndex = vi; + // create bottom skirt vertices + r=0; + for(c=0;c0;--c) + { + skirtDrawElements[ei++] = (r)*numColumns+c; + skirtDrawElements[ei++] = vi; + v[vi] = v[(r)*numColumns+c]+skirtVector; + t[vi++] = t[(r)*numColumns+c]; + } + // create left skirt vertices + c=0; + for(r=numRows-1;r>0;--r) + { + skirtDrawElements[ei++] = (r)*numColumns+c; + skirtDrawElements[ei++] = vi; + v[vi] = v[(r)*numColumns+c]+skirtVector; + t[vi++] = t[(r)*numColumns+c]; + } + skirtDrawElements[ei++] = 0; + skirtDrawElements[ei++] = firstSkirtVertexIndex; + } + + + + + osgUtil::TriStripVisitor tsv; + tsv.stripify(*geometry); +// +// osgUtil::SmoothingVisitor sv; +// sv.smooth(*geometry); + + osg::Vec4Array& tsgTangentArray = *(new osg::Vec4Array(1)); + osg::Vec4Array& tsgBinormalArray = *(new osg::Vec4Array(1)); + osg::Vec4Array& tsgNormalArray = *(new osg::Vec4Array(1)); + tsgTangentArray[0].set(1.0f,0.0f,0.0f,0.0f); + tsgBinormalArray[0].set(0.0f,1.0f,0.0f,0.0f); + tsgNormalArray[0].set(0.0f,0.0f,1.0f,0.0f); + geometry->setVertexAttribData(6, osg::Geometry::ArrayData(&tsgTangentArray, osg::Geometry::BIND_OVERALL,GL_FALSE)); + geometry->setVertexAttribData(7, osg::Geometry::ArrayData(&tsgBinormalArray, osg::Geometry::BIND_OVERALL,GL_FALSE)); + geometry->setVertexAttribData(15, osg::Geometry::ArrayData(&tsgNormalArray, osg::Geometry::BIND_OVERALL,GL_FALSE)); + + //geometry->setUseVertexBufferObjects(true); + + geometry->setUseDisplayList(false); + geometry->setUseVertexBufferObjects(false); + + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geometry); + + return geode; + +} + + +osg::Node* createQuadTree(osg::HeightField* grid, + unsigned int columnBegin, unsigned int columnEnd, + unsigned int rowBegin, unsigned int rowEnd, + float xTexCoordBegin, float xTexCoordEnd, + float yTexCoordBegin, float yTexCoordEnd, + unsigned int targetNumPolygonsPerTile) +{ + unsigned int numPolys = (columnEnd-columnBegin)*(rowEnd-rowBegin)*2; + + + std::cout << "createQuadTree "<getBound().radius()*4.0f; + float max_visible_distance = 1e7; + + unsigned int columnCenter = (columnBegin + columnEnd)/2; + unsigned int rowCenter = (rowBegin + rowEnd)/2; + float xTexCoordCenter = xTexCoordBegin+ + (xTexCoordEnd-xTexCoordBegin)*((float)(columnCenter-columnBegin)/(float)(columnEnd-columnBegin)); + float yTexCoordCenter = yTexCoordBegin+ + (yTexCoordEnd-yTexCoordBegin)*((float)(rowCenter-rowBegin)/(float)(rowEnd-rowBegin)); + + osg::Group* group = new osg::Group; + group->addChild(createQuadTree(grid, + columnBegin, columnCenter, + rowBegin, rowCenter, + xTexCoordBegin, xTexCoordCenter, + yTexCoordBegin, yTexCoordCenter, + targetNumPolygonsPerTile)); + + group->addChild(createQuadTree(grid, + columnCenter, columnEnd, + rowBegin, rowCenter, + xTexCoordCenter, xTexCoordEnd, + yTexCoordBegin, yTexCoordCenter, + targetNumPolygonsPerTile)); + + group->addChild(createQuadTree(grid, + columnCenter, columnEnd, + rowCenter, rowEnd, + xTexCoordCenter, xTexCoordEnd, + yTexCoordCenter, yTexCoordEnd, + targetNumPolygonsPerTile)); + + group->addChild(createQuadTree(grid, + columnBegin, columnCenter, + rowCenter, rowEnd, + xTexCoordBegin, xTexCoordCenter, + yTexCoordCenter, yTexCoordEnd, + targetNumPolygonsPerTile)); + + osg::LOD* lod = new osg::LOD; + lod->addChild(tile,cut_off_distance,max_visible_distance); + lod->addChild(group,0.0f,cut_off_distance); + + return lod; + + } +} + + +template< typename T> +void populate_z(osg::Image* image, const osg::Vec3& zAxis,osg::Vec3Array& v) +{ + unsigned char* ptr = image->data(); + unsigned int rowSizeInBytes = image->getRowSizeInBytes(); + unsigned int pixelSizeInBits = image->getPixelSizeInBits(); + unsigned int pixelSizeInBytes = pixelSizeInBits/8; + + unsigned int numColumns = image->s(); + unsigned int numRows = image->t(); + for(unsigned int r=0,vi=0;r(image->getUserData()); + + unsigned int numColumns = image->s(); + unsigned int numRows = image->t(); + unsigned int r; + unsigned int c; + + osg::Geode* geode = new osg::Geode; + + bool useGeometry = true; + if (useGeometry) + { + + osg::Geometry* geometry = new osg::Geometry; + + osg::Vec3Array& v = *(new osg::Vec3Array(numColumns*numRows)); + //osg::Vec3Array& n = *(new osg::Vec3Array(numColumns*numRows)); + osg::Vec2Array& t = *(new osg::Vec2Array(numColumns*numRows)); + osg::UByte4Array& color = *(new osg::UByte4Array(1)); + + color[0].set(255,255,255,255); + + +#if 0 + osg::Vec2 tex_orig(0.0f,0.0f); + + float rowTexDelta = 1.0f/(float)(numRows-1); + float columnTexDelta = 1.0f/(float)(numColumns-1); +#else + + osg::Vec2 tex_orig(origin.x(),origin.y()); + + float columnTexDelta = xAxis.length()/(float)(numColumns-1); + float rowTexDelta = yAxis.length()/(float)(numRows-1); +#endif + + if (texCoordRange) + { +// tex_orig.set(texCoordRange->_x,texCoordRange->_y); +// rowTexDelta = texCoordRange->_h/(float)(numRows-1); +// columnTexDelta = texCoordRange->_w/(float)(numColumns-1); + + std::cout<<"setting tex values to use texCoordRange"<getDataType()) + { + case(GL_UNSIGNED_BYTE): populate_z(image,zAxis,v); break; + case(GL_BYTE): populate_z(image,zAxis,v); break; + case(GL_UNSIGNED_SHORT): populate_z(image,zAxis,v); break; + case(GL_SHORT): populate_z(image,zAxis,v); break; + case(GL_UNSIGNED_INT): populate_z(image,zAxis,v); break; + case(GL_INT): populate_z(image,zAxis,v); break; + case(GL_FLOAT): populate_z(image,zAxis,v); break; + } + + geometry->setVertexArray(&v); + //geometry->setNormalArray(&n); + //geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + geometry->setColorArray(&color); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + geometry->setTexCoordArray(0,&t); + geometry->setTexCoordArray(1,&t); + + + for(r=0;raddPrimitiveSet(&drawElements); + int ei=0; + for(c=0;csetVertexAttribData(6, osg::Geometry::ArrayData(&tsgTangentArray, osg::Geometry::BIND_OVERALL,GL_FALSE)); + geometry->setVertexAttribData(7, osg::Geometry::ArrayData(&tsgBinormalArray, osg::Geometry::BIND_OVERALL,GL_FALSE)); + geometry->setVertexAttribData(15, osg::Geometry::ArrayData(&tsgNormalArray, osg::Geometry::BIND_OVERALL,GL_FALSE)); + + //geometry->setUseVertexBufferObjects(true); + + geometry->setUseDisplayList(false); + geometry->setUseVertexBufferObjects(false); + + geode->addDrawable(geometry); + } + else + { + + osg::HeightField* grid = createHeightField(image,origin,osg::Vec3(xAxis.length(),yAxis.length(),zAxis.length())); + + geode->addDrawable(new osg::ShapeDrawable(grid)); + } + + return geode; +} + +osg::Node* computeGeometry(osg::Image* image, const osg::Vec3& origin, const osg::Vec3& size) +{ + return computeGeometry(image,origin,osg::Vec3(size.x(),0.0f,0.0f),osg::Vec3(0.0f,size.y(),0.0f),osg::Vec3(0.0f,0.0f,size.z())); +} + +osg::Node* createTile(const std::string& filename, double x, double y, double w,double h) +{ + + osg::ref_ptr options = new osgDB::ImageOptions; + options->_sourceImageWindowMode = osgDB::ImageOptions::RATIO_WINDOW; + options->_sourceRatioWindow.set(x,1-(y+h),w,h); + + options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW; + options->_destinationPixelWindow.set(0,0,20,20); + + osgDB::Registry::instance()->setOptions(options.get()); + osg::Image* image = osgDB::readImageFile(filename.c_str()); + if (image) + { + + return computeGeometry(image,osg::Vec3(x,y,0.0),osg::Vec3(w,h,VERTICAL_SIZE)); + + } + else + { + return 0; + } +} + +osg::Node* createTileAndRecurse(const std::string& filename, const std::string& basename, const std::string& extension, unsigned int noTilesX, unsigned int noTilesY, double x, double y, double w,double h, unsigned int numLevelsLeft) +{ + + osg::Group* group = new osg::Group; + + double dx = w / (double) noTilesX; + double dy = h / (double) noTilesY; + + + if (numLevelsLeft>0) + { + + float cut_off_distance = 4.0f*dy; + float max_visible_distance = 1e7; + + // create current layer, and write to disk. + unsigned int numTiles = 0; + double lx = x; + for(unsigned i=0;i node = createTileAndRecurse(filename,lbasename,extension,2,2,lx,ly,dx,dy,numLevelsLeft-1); + osgDB::writeNodeFile(*node, lbasename+extension); + } + + // create PagedLOD for tile. + osg::PagedLOD* pagedlod = new osg::PagedLOD; + osg::Node* tile = createTile(filename,lx,ly,dx,dy); + pagedlod->addChild(tile, cut_off_distance,max_visible_distance); + pagedlod->setRange(1,0.0f,cut_off_distance); + pagedlod->setFileName(1,lbasename+extension); + pagedlod->setCenter(tile->getBound().center()); + + group->addChild(pagedlod); + + // increment number of tiles. + ++numTiles; + } + + } + + } + else + { + double lx = x; + for(unsigned i=0;iaddChild(createTile(filename,lx,ly,dx,dy)); + } + } + } + + + return group; + +} + +bool createWorld(const std::string& inputFile, const std::string& baseName, unsigned int numLevels) +{ + + osgDB::ReaderWriter* readerWriter = osgDB::Registry::instance()->getReaderWriterForExtension("gdal"); + if (!readerWriter) + { + std::cout<<"Error: GDAL plugin not available, cannot preceed with database creation"< options = new osgDB::ImageOptions; + options->_sourceImageWindowMode = osgDB::ImageOptions::RATIO_WINDOW; + options->_sourceRatioWindow.set(0,0,1,1); + + options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW; + options->_destinationPixelWindow.set(0,0,512,512); + + 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"); + + + scene = createQuadTree(grid, + 0, grid->getNumColumns()-1, + 0, grid->getNumRows()-1, + 0.0f, 1.0f, + 0.0f, 1.0f, + 2000); + + } + + + } + + // generate diffuse map + osg::Image* diffuseMap = 0; +// { +// osg::ref_ptr options = new osgDB::ImageOptions; +// options->_sourceImageWindowMode = osgDB::ImageOptions::RATIO_WINDOW; +// options->_sourceRatioWindow.set(0,0,1,1); +// +// options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW; +// options->_destinationPixelWindow.set(0,0,2048,2048); +// +// osgDB::Registry::instance()->setOptions(options.get()); +// diffuseMap = osgDB::readImageFile(inputFile.c_str()); +// if (diffuseMap) +// { +// diffuseMap->setFileName("diffuse.rgb"); +// osgDB::writeImageFile(*diffuseMap,"diffuse.rgb"); +// } +// +// } + + diffuseMap = osgDB::readImageFile("LlanoTex.jpg"); + + + osg::Texture2D* diffuseMapTexture = new osg::Texture2D(diffuseMap); + osg::Texture2D* normalMapTexture = new osg::Texture2D(normalMap); + + // create osgFX::BumpingMapping + osg::ref_ptr bumpMap = new osgFX::BumpMapping; + bumpMap->setLightNumber(0); + bumpMap->setNormalMapTextureUnit(0); + bumpMap->setDiffuseTextureUnit(1); + bumpMap->setOverrideDiffuseTexture(diffuseMapTexture); + bumpMap->setOverrideNormalMapTexture(normalMapTexture); + + bumpMap->addChild(scene.get()); + +#ifdef USE_PREPARE + bumpMap->prepareChildren(); +#endif + + osg::ref_ptr group = new osg::Group; + + + group->addChild(bumpMap.get()); + + osg::StateSet* stateset = group->getOrCreateStateSet(); + stateset->setMode(GL_CULL_FACE,osg::StateAttribute::ON); + + osgDB::writeNodeFile(*group, baseName); + + } + else + { + + osg::ref_ptr group = new osg::Group; + group->addChild(createTileAndRecurse(inputFile, base, extension, 2,2, 0.0, 0.0, 1.0, 1.0, numLevels)); + + osg::StateSet* stateset = group->getOrCreateStateSet(); + stateset->setMode(GL_CULL_FACE,osg::StateAttribute::ON); + + osgDB::writeNodeFile(*group, baseName); + + } + + osg::Timer_t end_tick = timer.tick(); + std::cout << "Time to create world "<setApplicationName(arguments.getApplicationName()); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-i ","Specify the input file to process"); + arguments.getApplicationUsage()->addCommandLineOption("-o ","Specify the output master file to generate"); + arguments.getApplicationUsage()->addCommandLineOption("-l ","Specify the number of PagedLOD levels to generate"); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + + std::string inputFile; + while (arguments.read("-i",inputFile)) {} + + std::string basename("output.ive"); + while (arguments.read("-o",basename)) {} + + float numLevels; + while (arguments.read("-l",numLevels)) {} + + while (arguments.read("-v",VERTICAL_SIZE)) {} + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } + +// if (arguments.argc()<=1) +// { +// arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); +// return 1; +// } + + + + // create a graphics context to allow us to use OpenGL to compress textures. + GraphicsContext gfx; + + createWorld(inputFile,basename,(unsigned int)numLevels); + + return 0; +} + diff --git a/examples/osgforest/osgforest.cpp b/examples/osgforest/osgforest.cpp index 2369d5869..79ed5c199 100644 --- a/examples/osgforest/osgforest.cpp +++ b/examples/osgforest/osgforest.cpp @@ -384,7 +384,7 @@ osg::Geode* ForestTechniqueManager::createTerrain(const osg::Vec3& origin, const if (createGrid) { - osg::Grid* grid = new osg::Grid; + osg::HeightField* grid = new osg::HeightField; grid->allocateGrid(numColumns,numRows); grid->setOrigin(origin); grid->setXInterval(size.x()/(float)(numColumns-1)); diff --git a/examples/osgshadowtexture/osgshadowtexture.cpp b/examples/osgshadowtexture/osgshadowtexture.cpp index 567fc3db6..929f82434 100644 --- a/examples/osgshadowtexture/osgshadowtexture.cpp +++ b/examples/osgshadowtexture/osgshadowtexture.cpp @@ -68,7 +68,7 @@ osg::Node* createBase(const osg::Vec3& center,float radius) geode->setStateSet( stateset ); - osg::Grid* grid = new osg::Grid; + osg::HeightField* grid = new osg::HeightField; grid->allocateGrid(38,39); grid->setOrigin(center+osg::Vec3(-radius,-radius,0.0f)); grid->setXInterval(radius*2.0f/(float)(38-1)); diff --git a/examples/osgshape/osgshape.cpp b/examples/osgshape/osgshape.cpp index 6412fdaf7..e9c03086a 100644 --- a/examples/osgshape/osgshape.cpp +++ b/examples/osgshape/osgshape.cpp @@ -42,7 +42,7 @@ osg::Geode* createShapes() geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(4.0f,0.0f,0.0f),radius,height),hints)); geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(6.0f,0.0f,0.0f),radius,height),hints)); - osg::Grid* grid = new osg::Grid; + osg::HeightField* grid = new osg::HeightField; grid->allocateGrid(38,39); grid->setXInterval(0.28f); grid->setYInterval(0.28f); diff --git a/include/osg/Shape b/include/osg/Shape index bdf53f661..3001255af 100644 --- a/include/osg/Shape +++ b/include/osg/Shape @@ -418,21 +418,25 @@ class SG_EXPORT HeightField : public Shape { public: - HeightField() {} - - HeightField(const HeightField& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY): - Shape(mesh,copyop), + HeightField(): _columns(0), _rows(0), _origin(0.0f,0.0f,0.0f), _dx(1.0f), _dy(1.0f) {} + + HeightField(const HeightField& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + Shape(mesh,copyop), + _columns(mesh._columns), + _rows(mesh._rows), + _origin(mesh._origin), + _dx(mesh._dx), + _dy(mesh._dy), + _heights(mesh._heights) {} - virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } - virtual const char* libraryName() const { return "osg"; } - virtual const char* className() const { return "HeightField"; } - virtual void accept(osg::ShapeVisitor& sv) { sv.apply(*this); } - virtual void accept(osg::ConstShapeVisitor& csv) const { csv.apply(*this); } + META_Shape(osg, HeightField) + + void allocateGrid(unsigned int numColumns,unsigned int numRows); inline unsigned int getNumColumns() const { return _columns; } inline unsigned int getNumRows() const { return _rows; } @@ -446,9 +450,23 @@ class SG_EXPORT HeightField : public Shape inline void setYInterval(float dy) { _dy = dy; } inline float getYInterval() const { return _dy; } - virtual float getHeight(unsigned int c,unsigned int r) const = 0; - - virtual Vec3 getNormal(unsigned int c,unsigned int r) const; + + inline void setHeight(unsigned int c,unsigned int r,float value) + { + _heights[c+r*_columns] = value; + } + + inline float& getHeight(unsigned int c,unsigned int r) + { + return _heights[c+r*_columns]; + } + + inline float getHeight(unsigned int c,unsigned int r) const + { + return _heights[c+r*_columns]; + } + + Vec3 getNormal(unsigned int c,unsigned int r) const; inline void setRotation(const Quat& quat) { _rotation = quat; } inline const Quat& getRotation() const { return _rotation; } @@ -467,39 +485,11 @@ class SG_EXPORT HeightField : public Shape Quat _rotation; -}; - -class SG_EXPORT Grid : public HeightField -{ - public: - - Grid(); - - Grid(const Grid& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY); - - META_Shape(osg,Grid); - - void allocateGrid(unsigned int numColumns,unsigned int numRows); - - void setHeight(unsigned int c,unsigned int r,float value) - { - _heights[c+r*_columns] = value; - } - - virtual float getHeight(unsigned int c,unsigned int r) const - { - return _heights[c+r*_columns]; - } - - protected: - - ~Grid(); - typedef std::vector HeightList; HeightList _heights; - }; + class CompositeShape : public Shape { public: diff --git a/include/osgDB/ImageOptions b/include/osgDB/ImageOptions index 72e277763..d9a7fe3e4 100644 --- a/include/osgDB/ImageOptions +++ b/include/osgDB/ImageOptions @@ -86,24 +86,43 @@ class OSGDB_EXPORT ImageOptions : public osgDB::ReaderWriter::Options CUBIC }; + /** Used as UserData attached to generated osg::Image's*/ + struct TexCoordRange : public osg::Referenced + { + TexCoordRange(): + _x(0.0), + _y(0.0), + _w(1.0), + _h(1.0) {} + + void set(double x,double y, double w, double h) + { + _x = x; + _y = y; + _w = w; + _h = h; + } + + double _x,_y,_w,_h; + }; + + // source ImageSamplingMode _sourceImageSamplingMode; ImageWindowMode _sourceImageWindowMode; RatioWindow _sourceRatioWindow; PixelWindow _sourcePixelWindow; - - // destination osg::ref_ptr _destinationImage; - + ImageWindowMode _destinationImageWindowMode; RatioWindow _destinationRatioWindow; PixelWindow _destinationPixelWindow; - + GLenum _destinationDataType; GLenum _destinationPixelFormat; - + void init(); }; diff --git a/include/osgGA/AnimationPathManipulator b/include/osgGA/AnimationPathManipulator index 8c6686c64..7e5ee724d 100644 --- a/include/osgGA/AnimationPathManipulator +++ b/include/osgGA/AnimationPathManipulator @@ -21,7 +21,7 @@ namespace osgGA{ // -// The AnimationPathManipulator is a Camera Manipulator that reads an +// The AnimationPathManipulator is a Matrix Manipulator that reads an // animation path from a file and plays it back. The file is expected // to be ascii and a succession of lines with 8 floating point values // per line. The succession of values are: diff --git a/src/osg/Shape.cpp b/src/osg/Shape.cpp index fe93d4d65..c47afe1a2 100644 --- a/src/osg/Shape.cpp +++ b/src/osg/Shape.cpp @@ -15,6 +15,16 @@ using namespace osg; +void HeightField::allocateGrid(unsigned int numColumns,unsigned int numRows) +{ + if (_columns!=numColumns || _rows!=numRows) + { + _heights.resize(numColumns*numRows); + } + _columns=numColumns; + _rows=numRows; +} + Vec3 HeightField::getNormal(unsigned int c,unsigned int r) const { // four point normal generation. @@ -53,27 +63,4 @@ Vec3 HeightField::getNormal(unsigned int c,unsigned int r) const return normal; } -Grid::Grid() -{ -} - -Grid::Grid(const Grid& mesh,const CopyOp& copyop): - HeightField(mesh,copyop) -{ - _heights = mesh._heights; -} - -Grid::~Grid() -{ -} - -void Grid::allocateGrid(unsigned int numColumns,unsigned int numRows) -{ - if (_columns!=numColumns || _rows!=numRows) - { - _heights.resize(numColumns*numRows); - } - _columns=numColumns; - _rows=numRows; -} diff --git a/src/osgPlugins/gdal/ReaderWriterGDAL.cpp b/src/osgPlugins/gdal/ReaderWriterGDAL.cpp index 71201cc87..93009e6f6 100644 --- a/src/osgPlugins/gdal/ReaderWriterGDAL.cpp +++ b/src/osgPlugins/gdal/ReaderWriterGDAL.cpp @@ -42,18 +42,35 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter 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): - windowX = osg::maximum((int)(floor((double)dataWidth * imageOptions->_sourceRatioWindow.windowX)),0); - windowY = osg::maximum((int)(floor((double)dataHeight * imageOptions->_sourceRatioWindow.windowY)),0); - windowWidth = osg::minimum((int)(ceil((double)dataWidth * (imageOptions->_sourceRatioWindow.windowX + imageOptions->_sourceRatioWindow.windowWidth))),dataWidth)-windowX; - windowHeight = osg::minimum((int)(ceil((double)dataHeight * (imageOptions->_sourceRatioWindow.windowY + imageOptions->_sourceRatioWindow.windowHeight))),dataHeight)-windowY; + { + 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; @@ -145,6 +162,7 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter else if (band->GetColorInterpretation()==GCI_GreenBand) bandGreen = band; else if (band->GetColorInterpretation()==GCI_BlueBand) bandBlue = band; else if (band->GetColorInterpretation()==GCI_AlphaBand) bandAlpha = band; + else bandGray = band; // int gotMin,gotMax; // double minmax[2]; @@ -281,7 +299,9 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter dataType, (unsigned char *)imageData, osg::Image::USE_NEW_DELETE); - + + if (texCoordRange) image->setUserData(texCoordRange); + image->flipVertical(); return image; diff --git a/src/osgPlugins/osg/Drawable.cpp b/src/osgPlugins/osg/Drawable.cpp index 6f1a46205..69631c8ca 100644 --- a/src/osgPlugins/osg/Drawable.cpp +++ b/src/osgPlugins/osg/Drawable.cpp @@ -73,6 +73,21 @@ bool Drawable_readLocalData(Object& obj, Input& fr) } } + if (fr[0].matchWord("useVertexBufferObjects")) + { + if (fr[1].matchWord("TRUE")) + { + drawable.setUseVertexBufferObjects(true); + fr+=2; + iteratorAdvanced = true; + } + else if (fr[1].matchWord("FALSE")) + { + drawable.setUseVertexBufferObjects(false); + fr+=2; + iteratorAdvanced = true; + } + } return iteratorAdvanced; } @@ -103,6 +118,9 @@ bool Drawable_writeLocalData(const Object& obj, Output& fw) if (drawable.getUseDisplayList()) fw << "TRUE" << std::endl; else fw << "FALSE" << std::endl; + fw.indent()<<"useVertexBufferObjects "; + if (drawable.getUseVertexBufferObjects()) fw << "TRUE" << std::endl; + else fw << "FALSE" << std::endl; return true; } diff --git a/src/osgPlugins/osg/Shape.cpp b/src/osgPlugins/osg/Shape.cpp index a5f21b5f0..b03ca8360 100644 --- a/src/osgPlugins/osg/Shape.cpp +++ b/src/osgPlugins/osg/Shape.cpp @@ -305,14 +305,25 @@ bool HeightField_writeLocalData(const Object& obj, Output& fw); //register the read and write functions with the osgDB::Registry. RegisterDotOsgWrapperProxy g_HeightFieldFuncProxy ( - 0, + new osg::HeightField, "HeightField", - "Object HieghtField", + "Object HeightField", &HeightField_readLocalData, &HeightField_writeLocalData, DotOsgWrapper::READ_AND_WRITE ); +//register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_GridFuncProxy +( + new osg::HeightField, + "Grid", + "Object HeightField", + 0, + 0, + DotOsgWrapper::READ_AND_WRITE +); + bool HeightField_readLocalData(Object& obj, Input& fr) { bool iteratorAdvanced = false; @@ -359,49 +370,12 @@ bool HeightField_readLocalData(Object& obj, Input& fr) iteratorAdvanced = true; } - return iteratorAdvanced; -} - -bool HeightField_writeLocalData(const Object& obj, Output& fw) -{ - const HeightField& heightfield = static_cast(obj); - - fw.indent()<<"Origin "<(obj); - if (fr.matchSequence("NumColumnsAndRows %i %i")) { int numcolumns,numrows; fr[1].getInt(numcolumns); fr[2].getInt(numrows); - grid.allocateGrid(numcolumns,numrows); + heightfield.allocateGrid(numcolumns,numrows); fr+=3; iteratorAdvanced = true; } @@ -421,9 +395,9 @@ bool Grid_readLocalData(Object& obj, Input& fr) { if (fr.readSequence(height)) { - grid.setHeight(column,row,height); + heightfield.setHeight(column,row,height); ++column; - if (column>=grid.getNumColumns()) + if (column>=heightfield.getNumColumns()) { column = 0; ++row; @@ -440,25 +414,29 @@ bool Grid_readLocalData(Object& obj, Input& fr) } - return iteratorAdvanced; } -bool Grid_writeLocalData(const Object& obj, Output& fw) +bool HeightField_writeLocalData(const Object& obj, Output& fw) { - const Grid& grid = static_cast(obj); + const HeightField& heightfield = static_cast(obj); - fw.indent()<<"NumColumnsAndRows "<