Hi Mark,

The Optimizer by default will set up textures to unref their
osg::Image after being applied to OpenGL, this is done to reduce the
memory footprint the application requires, but alas has the downside
of causing problems with later trying to get the original filename
that the Image was sourced from.

To fix this just select you own Optimizer mask which doesn't include
the optimizer textyure settings pass when you call optimizer.  See the
include/osgUtil/Optimizer for details on the mask.

Robert.

On 1/4/07, Mark W <[EMAIL PROTECTED]> wrote:
Hey all!  I have a simple program that loads in a 3D model and then uses
a node visitor to print out some data about the model.  One piece of
data that the node visitor is printing is the model's texture filename.
The code from the node visitor to do this appears as follows:

/***************[Begin Code]***************************/

// The apply(osg::Geode) function looks through the drawables in the
geode and calls this apply function
// for the osg::StateSet of each drawable found.
void TextureChangeVisitor::apply(osg::StateSet* stateset)
{
     if (stateset)
     {
          for(unsigned int
i=0;i<stateset->getTextureAttributeList().size();++i)
          {
               osg::Texture2D* texture =
dynamic_cast<osg::Texture2D*>(stateset->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
               if (texture)
               {
                    if(texture->getImage())
                         std::cout << "-Texture File: " <<
texture->getImage()->getFileName() << std::endl;
                    else
                         std::cout << "Error, Invalid Image!" << std::endl;
               }
          }
     }
}

/***************[End Code]***************************/

If I use this node visitor to traverse my model anywhere in my program
after my call to osgDB::readNodeFile(), the texture filename is printed
out as normal.  If I pass the model to my keyboard handler though, and
try to traverse with my node visitor each time a key is pressed, it will
not be able to get a valid image from the texture (so the program prints
the "Error, Invalid Image!" line from the above function).

Here is the code for the rest of the program.  The keyboard handler, the
model loading function, and the main.  Does anyone have any idea why I
the above code doesn't work when executed from inside the
KeyboardEventHandler class?

/***************[Begin Code]***************************/

///
//  class KeyboardEventHandler
///
/// Handle keyboard input from the user
///
/// This class is able to read keyboard input.
/// In this program, it is merely used to check
/// for any key being pressed.  If a key is
/// pressed, we will attempt to toggle our model
/// texture
///
class KeyboardEventHandler : public osgGA::GUIEventHandler
{
public:

     KeyboardEventHandler(osg::ref_ptr<osg::Node>& input_model):
model(input_model)
     {
     }

     virtual bool handle(const osgGA::GUIEventAdapter&
ea,osgGA::GUIActionAdapter&)
     {
          switch(ea.getEventType())
          {
               case(osgGA::GUIEventAdapter::KEYUP):
               {
                    // Using the node visitor to traverse here does not
work!
                    TextureChangeVisitor tex_nv;
                    model->asGroup()->traverse(tex_nv);
                    return true;
               }

               default:
               {
                    return false;
               }
          }
     }

     virtual void accept(osgGA::GUIEventHandlerVisitor& v)
     {
          v.visit(*this);
     }

private:
     osg::ref_ptr<osg::Node>& model;
};

///
//  LoadModel
///
/// Load in a 3D model (of any file type compatible with OpenSceneGraph).
///
/// This function uses the built in OSG model loader
/// function to open a file.  This function will open
/// any model type that OSG can normally load (and any
/// others that the user has the appropriate plugin for).
///
osg::Node* LoadModel(const std::string modelFile)
{
     // Read in the model file
     osg::Node* model = osgDB::readNodeFile("Models/Plane/Hat_01.3DS");

     // If the model failed to load...
     if(!model)
     {
          // ... generate an error and exit the program
          std::cout << "Program failed to load " << modelFile << std::endl;
          exit(1);
     }

     // Create a new optimizer to optimize the model
     osgUtil::Optimizer optimizer;
     optimizer.optimize(model);

     // The traversal works just fine here!
     TextureChangeVisitor tex_nv;
     model->asGroup()->traverse(tex_nv);

     // return our loaded model
     return(model);
}

///
//  main
///
/// The main function of the TextureChanger project.
///
/// This is our program entry point.  The main function
/// does all the command line parsing for the program.
/// It also uses the LoadModel function to load in a 3D
/// model.
///
int main (int argc, char** argv)
{
     // Create a standard Producer-based viewer
     osgProducer::Viewer viewer;
     viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);

     // Reference counted model
     osg::ref_ptr<osg::Node> model;

     // Load in the model
     model = LoadModel("");

     KeyboardEventHandler* keh = new KeyboardEventHandler(model);
     viewer.getEventHandlerList().push_front(keh);

     // add model to the viewer to be drawn
     viewer.setSceneData( model.get() );

     // Enter rendering loop
     viewer.realize();

     while (!viewer.done())
     {
          // wait for all cull and draw threads to complete.
          viewer.sync();

          // update the scene by traversing it with the the update
visitor which will
          // call all node update callbacks and animations.
          viewer.update();

          // fire off the cull and draw traversals of the scene.
          viewer.frame();
     }

      // Wait for all cull and draw threads to complete before exit.
      viewer.sync();
}

/***************[End Code]***************************/

Finally, here is some sample output to show exactly what is going wrong:

-GEODE
  -There is/are 1 drawables in this geode:
      -Drawable #0
        -Vertex Array contains 1209 vertices
          -The array is of type: 10
        -Texture Coordinate Array contains 1209 texture points
          -The array is of type: 9
        -Texture File: Models/Plane/Hat_01.tga    <---[ This is what
should happen]
        -Values are stored as triangles
          -There are 1833 indices
          -The max index value is: 1208
          -The min index value is: 0
-GEODE
  -There is/are 1 drawables in this geode:
      -Drawable #0
        -Vertex Array contains 1209 vertices
          -The array is of type: 10
        -Texture Coordinate Array contains 1209 texture points
          -The array is of type: 9
Error, Invalid Image!     <---[ when called from the KeyboardEventHandler]
        -Values are stored as triangles
          -There are 1833 indices
          -The max index value is: 1208
          -The min index value is: 0
-GEODE
  -There is/are 1 drawables in this geode:
      -Drawable #0
        -Vertex Array contains 1209 vertices
          -The array is of type: 10
        -Texture Coordinate Array contains 1209 texture points
          -The array is of type: 9
Error, Invalid Image!     <---[ when called from the KeyboardEventHandler]
        -Values are stored as triangles
          -There are 1833 indices
          -The max index value is: 1208
          -The min index value is: 0


Thanks in advance for any help anyone can offer!

-Mark Waligora
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

Reply via email to