Hi Mark,

I've been reviewing the Texture2D.cpp and Texture.cpp code and it
looks like it will try to rescale only the fly the incoming image,
using gluScaleImge, if it's different from the original image size.
This isn't necessarily the right thing to happen in this case, but it
shouldn't directly cause the OpenGL errors you are seeing.

Supporting resize of the image after first creation doesn't mean that
the texture sizes would need to be pushed into the per context buffer
objects, but this would then break osg::Texture's ability to set the
size externally such as in cases where you don't have an image, but
want to create a texture to operate on later such as a texture copy/or
FBO target - so your suggestion of making this parameter complete
immutable is just not viable.

I can't think of scheme of the top of my head which would fix the need
to external define texture size vs having it's size update on the fly
on a per context basis.  I'll will need to ponder on this issue.

For your own application the work around right now would to use an new
Texture and new Image, or call releaseGLObjects on the Texture.

Robert.

On Mon, Dec 15, 2008 at 7:34 PM, Mark Sciabica <[email protected]> wrote:
> 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
>
>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to