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/

Reply via email to