[osg-users] How to change a texture in a imported OSG file?

413 views
Skip to first unread message

Almir Brazil

unread,
Feb 14, 2011, 8:24:30 PM2/14/11
to osg-...@lists.openscenegraph.org
Hi,

I'm new to OpenSceneGraph, and I have the following scenario:

A OSG file exported from 3DS Max, using OSGExp0.9.8....
That file has 3 textures... 2 should be static, and 1 should be animated. When playing the exported OSG file, all 3 textures still static.

I read few things about osg imagesequence, that can read a lot of sequential images to produce a animated texture effect. And that's what I'm looking for!!

My dificultie is to change (in code) the static texture exported from 3DSMax to a imagesequence texture.

Can anyone say me how to do that?

...

Thank you!

Cheers,
Almir

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=36665#36665

_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Sergey Polischuk

unread,
Feb 15, 2011, 11:16:15 AM2/15/11
to osg-...@lists.openscenegraph.org
Hi, Almir

Try following thing:
Look at material name which uses this texture in 3ds max, in osg this will be the name of drawable with stateset that uses this texture. You can find this drawable with some visitor, get stateset there, then set your animated texture to texture unit where old texture is (if there are one texture in material it's 0 by default).

Cheers,
Sergey.

15.02.2011, 04:24, "Almir Brazil" <almi...@gmail.com>:

Almir Brazil

unread,
Feb 15, 2011, 11:35:46 AM2/15/11
to osg-...@lists.openscenegraph.org
Great!

Can you give me a sample of code for doing that?
That can one of the default OSG samples or other example...

Thanks a lot!

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=36695#36695

Almir Brazil

unread,
Feb 15, 2011, 9:15:15 PM2/15/11
to osg-...@lists.openscenegraph.org

hybr wrote:
> Hi, Almir
>
> Try following thing:
> Look at material name which uses this texture in 3ds max, in osg this will be the name of drawable with stateset that uses this texture. You can find this drawable with some visitor, get stateset there, then set your animated texture to texture unit where old texture is (if there are one texture in material it's 0 by default).
>
> Cheers,
> Sergey.
>
> 15.02.2011, 04:24, "Almir Brazil" <>:

>
> > Hi,
> >
> > I'm new to OpenSceneGraph, and I have the following scenario:
> >
> > A OSG file exported from 3DS Max, using OSGExp0.9.8....
> > That file has 3 textures... 2 should be static, and 1 should be animated.  When playing the exported OSG file, all 3 textures still static.
> >
> > I read few things about osg imagesequence, that can read a lot of sequential images to produce a animated texture effect. And that's what I'm looking for!!
> >
> > My dificultie is to change (in code) the static texture exported from 3DSMax to a imagesequence texture.
> >
> > Can anyone say me how to do that?
> >
> > ...
> >
> > Thank you!
> >
> > Cheers,
> > Almir
> >
> > ------------------
> > Read this topic online here:
> > http://forum.openscenegraph.org/viewtopic.php?p=36665#36665
> >
> > _______________________________________________
> > osg-users mailing list
> >
> > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> >
> _______________________________________________
> osg-users mailing list
>
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
> ------------------
> Post generated by Mail2Forum


Ok, here is the code... It's a modified version of osgartsimple.cpp:

(see attachment)

The OSG file - karsten.osg - (generated with 3ds Max) has 3 main textures. I want to change one of them with a imagesequence or movie file (quicktime .mov)
(I have both of them).

I haven't a Geode object, only a VideoGeode... how can I create a stateset to change the texture?

Thanks!

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=36711#36711

osgartsimple.cpp

Sergey Polischuk

unread,
Feb 16, 2011, 5:20:38 AM2/16/11
to osg-...@lists.openscenegraph.org
Hi, Almir

there are visitor that find drawable by name for you

class GetDrawableByNameVisitor:public osg::NodeVisitor
{
public:
GetDrawableByNameVisitor(const std::string &name):osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN): m_name(name), result(0)
{
setNodeMaskOverride(0xffffffff);
setTraversalMask(0xffffffff);
}
using osg::NodeVisitor::apply;
void apply(osg::Geode& geode)
{
for (int i = 0; i< geode.getNumDrawables(); i++)
{
osg::Drawable* dr = geode.getDrawable(i);
if (dr->getName()==m_name)
result = dr;
}
}
osg::Drawable* getResult(){return result;}
private:
std::string m_name;
osg::Drawable* result;
};

so in your example you need something like

GetDrawableByNameVisitor gdbnv("name of your material in 3dsmax with texture you wanna change")
arTransformA->accept(gdbny);
if (gdbny.getResult())
{
osg::ImageStream* is = ...;//load your movie or whatever you got
osg::Texture2D* animatedTexture = new osg::Texture2D(is);
gdbny.getResult()->getOrCreateStateSet()->setTextureAttribute(0,animatedTexture,osg::StateAttribute::ON);
}


there can be case when your texture is not on 0 texture unit so you may need to go through like first 8 texture units with stateset getTextureAttribute(tex_unit_number, osg::StateAttribute::TEXTURE) and check which one texture unit have texture, then set your new texture created with imagestream to that texture unit with setTextureAttribute on stateset.

Cheers,
Sergey.

16.02.2011, 05:15, "Almir Brazil" <almi...@gmail.com>:

> /* -*-c++-*-
>  *
>  * osgART - ARToolKit for OpenSceneGraph
>  * Copyright (C) 2005-2008 Human Interface Technology Laboratory New Zealand
>  *
>  * This file is part of osgART 2.0
>  *
>  * osgART 2.0 is free software: you can redistribute it and/or modify
>  * it under the terms of the GNU General Public License as published by
>  * the Free Software Foundation, either version 3 of the License, or
>  * (at your option) any later version.
>  *
>  * osgART 2.0 is distributed in the hope that it will be useful,
>  * but WITHOUT ANY WARRANTY; without even the implied warranty of
>  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>  * GNU General Public License for more details.
>  *
>  * You should have received a copy of the GNU General Public License
>  * along with osgART 2.0.  If not, see <http://www.gnu.org/licenses/>.
>  *
>  */
>
> #include <osgART/Foundation>
> #include <osgART/VideoLayer>
> #include <osgART/PluginManager>
> #include <osgART/VideoGeode>
> #include <osgART/Utils>
> #include <osgART/GeometryUtils>
> #include <osgART/MarkerCallback>
> #include <osgART/TransformFilterCallback>
>
> #include <osgViewer/Viewer>
> #include <osgViewer/ViewerEventHandlers>
>
> #include <osgDB/FileUtils>
>
> #include <osgDB/WriteFile>
> #include <osgDB/ReadFile>
> #include <osgDB/FileNameUtils>
> #include <osgDB/Registry>
>
> osg::Group* createImageBackground(osg::Image* video) {
>         osgART::VideoLayer* _layer = new osgART::VideoLayer();
>         _layer->setSize(*video);
>         osgART::VideoGeode* _geode = new osgART::VideoGeode(osgART::VideoGeode::USE_TEXTURE_2D, video);
>         addTexturedQuad(*_geode,video->s(),video->t());
>         _layer->addChild(_geode);
>         return _layer;
> }
>
> int main(int argc, char* argv[])  {
>
>         // create a root node
>         osg::ref_ptr<osg::Group> root = new osg::Group;
>
>         osgViewer::Viewer viewer;
>
>         // attach root node to the viewer
>         viewer.setSceneData(root.get());
>
>         // add relevant handlers to the viewer
>         viewer.addEventHandler(new osgViewer::StatsHandler);
>         viewer.addEventHandler(new osgViewer::WindowSizeHandler);
>         viewer.addEventHandler(new osgViewer::ThreadingHandler);
>         viewer.addEventHandler(new osgViewer::HelpHandler);
>
>         // preload the video and tracker
>         int _video_id = osgART::PluginManager::instance()->load("osgart_video_artoolkit2");
>         int _tracker_id = osgART::PluginManager::instance()->load("osgart_tracker_artoolkit2");
>
>         // Load a video plugin.
>         osg::ref_ptr<osgART::Video> video =
>                 dynamic_cast<osgART::Video*>(osgART::PluginManager::instance()->get(_video_id));
>
>         // check if an instance of the video stream could be started
>         if (!video.valid())
>         {
>                 // Without video an AR application can not work. Quit if none found.
>                 osg::notify(osg::FATAL) << "Could not initialize video plugin!" << std::endl;
>                 exit(-1);
>         }
>
>         // Open the video. This will not yet start the video stream but will
>         // get information about the format of the video which is essential
>         // for the connected tracker
>         video->open();
>
>         osg::ref_ptr<osgART::Tracker> tracker =
>                 dynamic_cast<osgART::Tracker*>(osgART::PluginManager::instance()->get(_tracker_id));
>
>         if (!tracker.valid())
>         {
>                 // Without tracker an AR application can not work. Quit if none found.
>                 osg::notify(osg::FATAL) << "Could not initialize tracker plugin!" << std::endl;
>                 exit(-1);
>         }
>
>         // get the tracker calibration object
>         osg::ref_ptr<osgART::Calibration> calibration = tracker->getOrCreateCalibration();
>
>         // load a calibration file
>         if (!calibration->load(std::string("data/camera_para.dat")))
>         {
>
>                 // the calibration file was non-existing or couldnt be loaded
>                 osg::notify(osg::FATAL) << "Non existing or incompatible calibration file" << std::endl;
>                 exit(-1);
>         }
>
>         // set the image source for the tracker
>         tracker->setImage(video.get());
>
>         osgART::TrackerCallback::addOrSet(root.get(), tracker.get());
>
>         osg::ref_ptr<osgART::Marker> markerA = tracker->addMarker("single;karsten_a.patt;70;0;0");
>
>         if (!markerA.valid())
>         {
>                 // Without marker an AR application can not work. Quit if none found.
>                 osg::notify(osg::FATAL) << "Could not add marker!" << std::endl;
>                 exit(-1);
>         }
>
>         markerA->setActive(true);
>
>         osg::ref_ptr<osg::MatrixTransform> arTransformA = new osg::MatrixTransform();
>         osgART::attachDefaultEventCallbacks(arTransformA.get(), markerA.get());
>         arTransformA->addChild(osgDB::readNodeFile("karsten.osg"));
>         arTransformA->getOrCreateStateSet()->setRenderBinDetails(100, "RenderBin");
>
>         osg::ref_ptr<osg::Group> videoBackground = createImageBackground(video.get());
>         videoBackground->getOrCreateStateSet()->setRenderBinDetails(0, "RenderBin");
>
>         osg::ref_ptr<osg::Camera> cam = calibration->createCamera();
>
>         cam->addChild(arTransformA.get());
>
>         cam->addChild(videoBackground.get());
>
>         root->addChild(cam.get());
>
>         video->start();
>         return viewer.run();


> }
>
> _______________________________________________
> osg-users mailing list
> osg-...@lists.openscenegraph.org

> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
_______________________________________________
osg-users mailing list

osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Almir Brazil

unread,
Feb 16, 2011, 9:54:26 AM2/16/11
to osg-...@lists.openscenegraph.org
> 16.02.2011, 05:15, "Almir Brazil" <>:

>
> > hybr wrote:
> >
> >
> > >  Hi, Almir
> > >
> > >  Try following thing:
> > >  Look at material name which uses this texture in 3ds max, in osg this will be the name of drawable with stateset that uses this texture. You can find this drawable with some visitor, get stateset there, then set your animated texture to texture unit where old texture is (if there are one texture in material it's 0 by default).
> > >
> > >  Cheers,
> > >  Sergey.
> > >
> > >  15.02.2011, 04:24, "Almir Brazil" <>:
> > >
> > > >  Hi,
> > > >
> > > >  I'm new to OpenSceneGraph, and I have the following scenario:
> > > >
> > > >  A OSG file exported from 3DS Max, using OSGExp0.9.8....
> > > >  That file has 3 textures... 2 should be static, and 1 should be animated.  When playing the exported OSG file, all 3 textures still static.
> > > >
> > > >  I read few things about osg imagesequence, that can read a lot of sequential images to produce a animated texture effect. And that's what I'm looking for!!
> > > >
> > > >  My dificultie is to change (in code) the static texture exported from 3DSMax to a imagesequence texture.
> > > >
> > > >  Can anyone say me how to do that?
> > > >
> > > >  ...
> > > >
> > > >  Thank you!
> > > >
> > > >  Cheers,
> > > >  Almir
> > > >
> > > >  ------------------
> > > >  Read this topic online here:
> > > >  http://forum.openscenegraph.org/viewtopic.php?p=36665#36665
> > > >
> > > >  _______________________________________________
> > > >  osg-users mailing list
> > > >
> > > >  http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> > > >
> > >  _______________________________________________
> > >  osg-users mailing list
> > >
> > >  http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> > >
> > >   ------------------
> > >  Post generated by Mail2Forum
> > >
> >
> > Ok, here is the code... It's a modified version of osgartsimple.cpp:
> >
> > (see attachment)
> >
> > The OSG file - karsten.osg - (generated with 3ds Max) has 3 main textures.  I want to change one of them with a imagesequence or movie file (quicktime .mov)
> > (I have both of them).
> >
> > I haven't a Geode object, only a VideoGeode... how can I create a stateset to change the texture?
> >
> > Thanks!
> >
> > ------------------
> > Read this topic online here:
> > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> >
> _______________________________________________
> osg-users mailing list
>
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
> ------------------
> Post generated by Mail2Forum


Hi hybr !

I'll try that tonight! :D

Thanks in advance!

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=36732#36732

Almir Brazil

unread,
Feb 16, 2011, 9:43:48 PM2/16/11
to osg-...@lists.openscenegraph.org
Hi hybr!

I can feel that I'm getting close.

I've done all what you say.. the project compile sucessfully, but I'm getting a black texture replacing my original static texture.
I tried all first 8 texture units, as you say.

I know that the imagestream is playing, because I can see the 'resize' messages in console.


Did I forget something?

(code attached below).


Thanks,
Almir

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=36755#36755

osgartsimple.cpp

Mourad Boufarguine

unread,
Feb 17, 2011, 4:19:49 AM2/17/11
to osg-...@lists.openscenegraph.org, Almir Brazil
Hi Almir,

You can open the osg file with a text editor and check the texture unit. Can you also check if it is a Texture2D or TextureRectangle ?

Mourad


Sergey Polischuk

unread,
Feb 17, 2011, 4:26:15 AM2/17/11
to osg-...@lists.openscenegraph.org
Hi Almir,

I feel like your best bet in this situation is save your scene on .osg (text) format and watch what's going on in text editor, and so with your original model. You can see what changes are and if they correct.

Cheers,
Sergey.

17.02.2011, 05:43, "Almir Brazil" <almi...@gmail.com>:

> #include <osg/NodeVisitor>


>
> osg::Group* createImageBackground(osg::Image* video) {
>         osgART::VideoLayer* _layer = new osgART::VideoLayer();
>         _layer->setSize(*video);
>         osgART::VideoGeode* _geode = new osgART::VideoGeode(osgART::VideoGeode::USE_TEXTURE_2D, video);
>         addTexturedQuad(*_geode,video->s(),video->t());
>         _layer->addChild(_geode);
>         return _layer;
> }
>

> class GetDrawableByNameVisitor : public osg::NodeVisitor {
> public:
>         GetDrawableByNameVisitor(const std::string &name):

>           osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), m_name(name), result(0)


>         {
>                 setNodeMaskOverride(0xffffffff);
>                 setTraversalMask(0xffffffff);
>         }
>
>           using osg::NodeVisitor::apply;
>
>           void apply(osg::Geode& geode)
>         {

>                 for (unsigned int i = 0; i <geode.getNumDrawables(); i++)


>                 {
>                         osg::Drawable* dr = geode.getDrawable(i);
>                         if (dr->getName()==m_name)
>                         result = dr;
>                 }
>         }
> osg::Drawable* getResult(){return result;}
>
> private:
>         std::string m_name;
>         osg::Drawable* result;
> };
>

>         GetDrawableByNameVisitor gdbny("Standard_3");
>         arTransformA->accept(gdbny);
>         if (gdbny.getResult())
>         {
>
>                 osg::Image* videocomp = osgDB::readImageFile("comp2.mov");
>                 osg::ImageStream* myImageStream = dynamic_cast<osg::ImageStream*>(videocomp);
>
>                 osg::Texture2D* animatedTexture = new osg::Texture2D(myImageStream);
>
>                 if(myImageStream->valid())
>         {
>             std::cout << "Got movie" << std::endl;
>                  myImageStream->play();
>                         //is->pause();
>         }
>         else
>         {
>             std::cout << "No movie!" << std::endl;
>                         exit(1);


>         }
>
>                 gdbny.getResult()->getOrCreateStateSet()->setTextureAttribute(0,animatedTexture,osg::StateAttribute::ON);
>         }
>

>         osg::ref_ptr<osg::Group> videoBackground = createImageBackground(video.get());
>         videoBackground->getOrCreateStateSet()->setRenderBinDetails(0, "RenderBin");
>
>         osg::ref_ptr<osg::Camera> cam = calibration->createCamera();
>
>         cam->addChild(arTransformA.get());
>
>         cam->addChild(videoBackground.get());
>
>         root->addChild(cam.get());
>
>         video->start();
>         return viewer.run();
> }
>
> _______________________________________________
> osg-users mailing list

> osg-...@lists.openscenegraph.org


> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
_______________________________________________
osg-users mailing list

osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Almir Brazil

unread,
Feb 17, 2011, 9:03:59 PM2/17/11
to osg-...@lists.openscenegraph.org

hybr wrote:
> Hi Almir,
>
> I feel like your best bet in this situation is save your scene on .osg (text) format and watch what's going on in text editor, and so with your original model. You can see what changes are and if they correct.
>
> Cheers,
> Sergey.
>
> 17.02.2011, 05:43, "Almir Brazil" <>:

>
> > Hi hybr!
> >
> > I can feel that I'm getting close.
> >
> > I've done all what you say..  the project compile sucessfully, but I'm getting a black texture replacing my original static texture.
> > I tried all first 8 texture units, as you say.
> >
> > I know that the imagestream is playing, because I can see the 'resize' messages in console.
> >
> > Did I forget something?
> >
> > (code attached below).
> >
> > Thanks,
> > Almir
> >
> > ------------------
> > Read this topic online here:
> > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> >
> _______________________________________________
> osg-users mailing list
>
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
> ------------------
> Post generated by Mail2Forum


Hi hybr!

That's working!!! Finally! :D
I installed the ffmpeg plugin and loaded the movie with .mov.ffmpeg extension. As you said before, the code is correct... only a plugin problem.
Only the audio is not playing... but that's no much important.

Thanks again!

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=36783#36783

Mourad Boufarguine

unread,
Feb 22, 2011, 4:59:53 AM2/22/11
to osg-...@lists.openscenegraph.org, Almir Brazil

That's working!!! Finally!  :D
I installed the ffmpeg plugin and loaded the movie with .mov.ffmpeg extension.  As you said before, the code is correct...  only a plugin problem.
Only the audio is not playing... but that's no much important.

Thanks again!


Hi Almir,

Glad it helped.
I think you can't get audio from ffmpeg plugin out of the box (although it already contains an audio decoder). I think you need to implement an osg::AudioSink to produce the sound. I found this thread that talks about an implementation of AudioSink (using SDL) used with the ffmpeg plugin :


Mourad 
Reply all
Reply to author
Forward
0 new messages