Hi Robert,

I'm unfamiliar with CompositeViewer so I set up my example using the objects I am familiar with. After examining CompositeViewer, it looks like it has the same problem but would be more difficult to set up a simple sample.

All that is needed to reproduce the problem is two distinct context IDs using the same texture. The texture needs to render in one of those contextIDs, change its size, then render in the other contextID. Rendering to the first contextID then fails because the texture does not look at the dimensions of its osg::Texture::TextureObject before doing a subload. It looks at its internal _textureWidth and _textureHeight members, which changed when the second context used the texture.

Step by step:
1. Create two contextIDs using the same Texture with Image having dimension AxB 2. Render contextID 1. This sets the texture's _textureHeight and _textureWidth to AxB. TextureObject for contextID 1 has size AxB.
3. Assign Image with dimension CxD to Texture.
4. Render contextID 2. This sets the texture's _textureHeight and _textureWidth to CxD. TextureObject for contextID 1 is still has size AxB! 5. Render contextID 1. Texture looks at its _textureHeight and _textureWidth and sees that it matches the image being used so tries to subload, even though the textureObject has the wrong dimensions.

So the problem appears to be reliance on these mutable members to keep track of state that is contextID specific. Either these mutables should be dropped (usually a good idea for mutables) or ignored, or contextID specific data should be flushed when mutable texture state changes.

Although I have no choice but to deal with multiple contextIDs in my application, I can avoid changing a texture's dimension (or simply call releaseGLObjects when doing so) so this is not a serious problem for me.

Mark

Robert Osfield wrote:
Hi Mark,

I don't recall any bug fixes on this topic.  The Texture code should
in theory reallocate when the sizes changes, and I'm sure I've
previously added code to do this.   Perhaps the awkward usage of the
OSG is what is causing the a crack to appear in the algorithm used.

I must say that your code is pretty perverse (using two viewers single
threaded in the same main loop), is there a reason why you have two
viewers in this code?  Can't you just use CompositeViewer to do this,
it's the class written to manage this type of application usage.   I
don't know whether this has barring on the problem, but it might.

Robert.

On Mon, Dec 15, 2008 at 5:16 PM, Mark Sciabica <[email protected]> wrote:
Hi Robert,

(I'm replying again for the benefit of those with threaded mail readers, and
so this thread won't be forgotten...)

I'm using osg version 2.6.0.

Mark

Robert Osfield wrote:

HI Mark,

I've previous used the ability of resizing images and it did have it
working.  I did require a bug fix, but this was done a while back.

Which version of the OSG are you using?

Robert.

On Thu, Dec 11, 2008 at 10:48 PM, Mark Sciabica <[email protected]>
wrote:


Hello Robert,

I have found a bug when assigning a new image to an existing texture that
already has an OpenGL texture object allocated. The problem appears to be
that Texture2D::apply is passing the wrong dimensions in to
applyTexImage2D_subload. Since the dimensions of the image don't match the
dimensions of the existing OpenGL texture object, subloading shouldn't even
be used. I therefore get the following error printed out on the console:

Warning: detected OpenGL error 'invalid value' after RenderBin::draw(,)

The dimensions of the Texture::TextureObject should be validated against the
data being loaded before calling subload, probably in the Texture*::apply
methods.

Mark

#include <osg/Texture2D>
#include <osg/Geometry>

#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>

int main()
{
   osg::ref_ptr<osg::Texture2D> texture1 = new osg::Texture2D;
   static unsigned char bytes[16] = {
       0xff, 0x00, 0x00, 0xff,
       0x00, 0xff, 0x00, 0xff,
       0x00, 0x00, 0xff, 0xff,
       0xff, 0x00, 0xff, 0xff,
   };
   osg::ref_ptr<osg::Image> imageRGB = new osg::Image;
   imageRGB->setImage(3, 1, 1, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
&bytes[0], osg::Image::NO_DELETE, 1);
   osg::ref_ptr<osg::Image> imageRed = new osg::Image;
   imageRed->setImage(1, 1, 1, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
&bytes[0], osg::Image::NO_DELETE, 1);
   osg::ref_ptr<osg::Image> imageGreen = new osg::Image;
   imageGreen->setImage(1, 1, 1, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
&bytes[4], osg::Image::NO_DELETE, 1);
   osg::ref_ptr<osg::Image> imageBlue = new osg::Image;
   imageBlue->setImage(1, 1, 1, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
&bytes[8], osg::Image::NO_DELETE, 1);


   osg::ref_ptr<osg::Geode> geode = new osg::Geode();
   osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();
   geode->addDrawable(geom.get());

   osg::ref_ptr<osg::Vec3Array> pVertices = new osg::Vec3Array;
   pVertices->push_back( osg::Vec3(0, 0, 0) );
   pVertices->push_back( osg::Vec3(0, 0, 1) );
   pVertices->push_back( osg::Vec3(1, 0, 1) );
   pVertices->push_back( osg::Vec3(1, 0, 0) );
   geom->setVertexArray(pVertices.get());

   osg::ref_ptr<osg::Vec2Array> pTexCoords = new osg::Vec2Array;
   pTexCoords->push_back( osg::Vec2(0, 0) );
   pTexCoords->push_back( osg::Vec2(0, 1) );
   pTexCoords->push_back( osg::Vec2(1, 1) );
   pTexCoords->push_back( osg::Vec2(1, 0) );
   geom->setTexCoordArray(0, pTexCoords.get());
   osg::ref_ptr<osg::DrawArrays> pDrawArrays = new osg::DrawArrays(GL_QUADS,
0, 4);
   geom->addPrimitiveSet(pDrawArrays.get());

   osg::StateSet* stateset = new osg::StateSet();
   stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
   stateset->setTextureAttributeAndModes(0, texture1.get(),
osg::StateAttribute::ON);
   geode->setStateSet( stateset );
   texture1->setImage(imageGreen.get());
   texture1->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
   texture1->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
   texture1->setResizeNonPowerOfTwoHint(false);
   texture1->setFilter( osg::Texture::MAG_FILTER, osg::Texture::NEAREST );
   texture1->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST );


   osg::ref_ptr<osgViewer::Viewer> viewer1 = new osgViewer::Viewer;
   osg::ref_ptr<osgViewer::Viewer> viewer2 = new osgViewer::Viewer;
   viewer1->setUpViewInWindow(20, 50, 200, 200);
   viewer2->setUpViewInWindow(240, 300, 200, 200);
   viewer1->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
   viewer2->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);

   viewer1->setSceneData( geode.get() );
   viewer2->setSceneData( geode.get() );

   viewer1->setCameraManipulator(new osgGA::TrackballManipulator());
   viewer2->setCameraManipulator(new osgGA::TrackballManipulator());

   int nFrame = 0;
   while( viewer1.get() || viewer2.get() )
   {
       if( viewer1.get() )
       {
           if( !viewer1->done() )
               viewer1->frame();
           else
               viewer1 = 0;
       }

       texture1->setImage(imageRGB.get());
       if( viewer2.get() )
       {
           if( !viewer2->done() )
               viewer2->frame();
           else
               viewer2 = 0;
       }

       ++nFrame;
   }

   return 0;
}


_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org




_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to