Hi,

attached patch should make this work, but before committing it I'd
appreciate it if Gerrit could take a look at it and/or if someone would
give it a try (I've also attached the test I used, which just writes new
data into the image each frame. The log messages from Window indicate
that only refreshes are performed).

        Thanks,
                Carsten

On Fri, 2007-08-17 at 18:53 +0200, Andreas Zieringer wrote:
> Hi Marcus,
> 
> > Gerrit Voss wrote:
> > 
> >>Hi,
> >>
> >>On Thu, 2007-08-16 at 17:25 +0800, Gerrit Voss wrote:
> >>  
> >>
> >>>Hi,
> >>>
> >>>On Thu, 2007-08-16 at 11:15 +0200, Marcus Lindblom wrote:
> >>>    
> >>>
> >>>>Dirk Reiners wrote:
> >>>>      
> >>>>
> >>>>> Hi Marcus,
> >>>>>
> >>>>>Marcus Lindblom wrote:
> >>>>>  
> >>>>>        
> >>>>
> >>>>I also tried doing it myself, using an MFTextureChunk field as 
> >>>>attachment, but I couldn't get the attachment to work as I wanted. I 
> >>>>failed to retrieve the attachment, even though I basically copied the 
> >>>>SimpleNameAttachment line for line.
> >>>>
> >>>>I could try to use the Parents field instead. That'd definitely be easier.
> >>>>      
> >>>
> >>>kind of, if you can take the 2.x image and texobjchunk as a reference
> >>>you will note that the changed interface was modified in order to choose
> >>>the right update method for the texture. In 1.x you most likely have to
> >>>force a reload the whole texture. I guess this was the main reason not
> >>>to automatically invalidate the texture as the image was changed. 
> >>>
> >>>Ideally this change should go back into 1.x. Otherwise people who rely
> >>>on the image not forcing a reload of the texture chunk will
> >>>experience a performance drop. Especially if the work with
> >>>TextureChunk::imageContentChanged.
> >>>    
> >>
> >>on a second thought the easier 1.x solution would be instead of calling
> >>the generic TextureChunk::changed you could downcast the parent and in
> >>case it really is a texture chunk invalidate it correctly depending
> >>on what of the image actually changed.
> >>  
> > 
> > I'm using 1.x, so that was my plan. :)
> 
> if I'm not wrong the parents field works only for the GeoProperties 
> right now, in all other cases it is empty.
> 
> Andreas
> 
? Source/System/State/testTextureChange.cpp
Index: Source/System/Image/OSGImage.cpp
===================================================================
RCS file: /cvsroot/opensg/OpenSG/Source/System/Image/OSGImage.cpp,v
retrieving revision 1.64
diff -u -r1.64 OSGImage.cpp
--- Source/System/Image/OSGImage.cpp	12 Jan 2007 17:49:23 -0000	1.64
+++ Source/System/Image/OSGImage.cpp	23 Aug 2007 23:28:40 -0000
@@ -52,6 +52,7 @@
 #include <OSGImageGenericAtt.h>
 #include <OSGFieldContainerFields.h>
 #include <OSGFileSystem.h>
+#include <OSGTextureChunk.h>
 
 #include "OSGImageFileHandler.h"
 #include "OSGPathHandler.h"
@@ -121,9 +122,21 @@
 
     while(parentsIt != parentsEnd)
     {
-        (*parentsIt)->changed(  TypeTraits<BitVector>::One <<
-                                    parentsIt->getParentFieldPos(),
-                                ChangedOrigin::Child);
+        // for TextureChunks we want to be careful whether a reinit or a
+        // refresh is triggered
+        TextureChunkPtr texParent = TextureChunkPtr::dcast(*parentsIt);
+        
+        if((texParent != NullFC) && ((whichField & ~(PixelFieldMask)) == 0))
+        {
+            texParent->imageContentChanged();
+        }
+        else
+        {
+            // call the generic change method        
+            (*parentsIt)->changed(
+                TypeTraits<BitVector>::One << parentsIt->getParentFieldPos(),
+                ChangedOrigin::Child                                         );
+        }
         ++parentsIt;
     }
     
Index: Source/System/Image/OSGImage.h
===================================================================
RCS file: /cvsroot/opensg/OpenSG/Source/System/Image/OSGImage.h,v
retrieving revision 1.26
diff -u -r1.26 OSGImage.h
--- Source/System/Image/OSGImage.h	12 Jan 2007 17:49:24 -0000	1.26
+++ Source/System/Image/OSGImage.h	23 Aug 2007 23:28:40 -0000
@@ -351,7 +351,15 @@
     UInt32 calcMipmapSumSize  ( UInt32 mipmapNum,
                                      UInt32 w, UInt32 h, UInt32 d) const;
     UInt32 calcMipmapSumSize  ( UInt32 mipmapNum                 ) const;
+    
+    /*! \}                                                                 */
+    /*---------------------------------------------------------------------*/
+    /*! \name                Set / Get Parents                             */
+    /*! \{                                                                 */
 
+    inline void addParent(const FieldContainerPtr &parent);
+    inline void subParent(const FieldContainerPtr &parent);
+    
     /*! \}                                                                 */
     /*=========================  PROTECTED  ===============================*/
   protected:
Index: Source/System/Image/OSGImage.inl
===================================================================
RCS file: /cvsroot/opensg/OpenSG/Source/System/Image/OSGImage.inl,v
retrieving revision 1.13
diff -u -r1.13 OSGImage.inl
--- Source/System/Image/OSGImage.inl	18 Nov 2005 10:33:31 -0000	1.13
+++ Source/System/Image/OSGImage.inl	23 Aug 2007 23:28:41 -0000
@@ -100,6 +100,31 @@
     return data;
 }
 
+/*! Add a field container as a parent of this Image.
+    
+    You should not have to call this method yourself.
+ */
+inline void
+Image::addParent(const FieldContainerPtr &parent)
+{
+    _mfParents.push_back(parent);
+}
+
+/*! Remove a field container as a parent of this Image.
+    
+    You should not have to call this method yourself.
+ */
+inline void
+Image::subParent(const FieldContainerPtr &parent)
+{
+    MFFieldContainerPtr::iterator parentIt = _mfParents.find(parent);
+    
+    if(parentIt != _mfParents.end())
+    {
+        _mfParents.erase(parentIt);
+    }
+}
+
 // Specialization for Image we need this to support VRML PixelTextures.
 template <> inline
 void SFImagePtr::pushValueByStr(const Char8 *str)
Index: Source/System/State/OSGTextureChunk.cpp
===================================================================
RCS file: /cvsroot/opensg/OpenSG/Source/System/State/OSGTextureChunk.cpp,v
retrieving revision 1.65
diff -u -r1.65 OSGTextureChunk.cpp
--- Source/System/State/OSGTextureChunk.cpp	20 Aug 2007 01:27:11 -0000	1.65
+++ Source/System/State/OSGTextureChunk.cpp	23 Aug 2007 23:28:41 -0000
@@ -282,12 +282,9 @@
         if((getMinFilter() != GL_NEAREST) &&
            (getMinFilter() != GL_LINEAR))
         {
-            if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
-            {
-                Window::reinitializeGLObject(getGLId());
-            }
+            triggerReInit();
         }
-        else
+        else // switching to GL_NEAREST or GL_LINEAR only requires refresh
         {
             imageContentChanged();
         }
@@ -300,17 +297,11 @@
                              DirtyMinYFieldMask | DirtyMaxYFieldMask |
                              DirtyMinZFieldMask | DirtyMaxZFieldMask)) == 0)
     {
-        if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
-        {
-            Window::refreshGLObject(getGLId());
-        }
+        triggerRefresh();
     }
     else // Play it safe, do a reinit
     {
-        if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
-        {
-            Window::reinitializeGLObject(getGLId());
-        }
+        triggerReInit();
     }
 
     if(whichField & ImageFieldMask)
Index: Source/System/State/OSGTextureChunk.h
===================================================================
RCS file: /cvsroot/opensg/OpenSG/Source/System/State/OSGTextureChunk.h,v
retrieving revision 1.21
diff -u -r1.21 OSGTextureChunk.h
--- Source/System/State/OSGTextureChunk.h	22 Mar 2007 10:07:45 -0000	1.21
+++ Source/System/State/OSGTextureChunk.h	23 Aug 2007 23:28:41 -0000
@@ -183,6 +183,9 @@
     /*! \name                         GL                                   */
     /*! \{                                                                 */
 
+    inline void triggerRefresh(void);
+    inline void triggerReInit (void);
+    
     void handleTexture(Window *win, UInt32 id, GLenum bindtarget,
                        GLenum paramtarget,
                        GLenum imgtarget, 
Index: Source/System/State/OSGTextureChunk.inl
===================================================================
RCS file: /cvsroot/opensg/OpenSG/Source/System/State/OSGTextureChunk.inl,v
retrieving revision 1.10
diff -u -r1.10 OSGTextureChunk.inl
--- Source/System/State/OSGTextureChunk.inl	9 Oct 2004 21:00:17 -0000	1.10
+++ Source/System/State/OSGTextureChunk.inl	23 Aug 2007 23:28:41 -0000
@@ -41,6 +41,8 @@
 #include "OSGConfig.h"
 #include "OSGBaseFunctions.h"
 
+#include "OSGImage.h"
+
 OSG_BEGIN_NAMESPACE
 
 inline
@@ -55,14 +57,33 @@
     return &TextureChunk::_class;
 }
 
+/*! Set the image used as texture by this chunk.
+
+    Images should only ever be set by calling this method, because it ensures
+    that this TextureChunk is registered as a parent of the image and thus
+    can be notified about changes to the image.
+ */
 inline
 void TextureChunk::setImage(ImagePtr &pImage)
 {
-     addRefCP(pImage);
+    if(_sfImage.getValue() != NullFC)
+    {
+        TextureChunkPtr thisPtr(*this);
+    
+        _sfImage.getValue()->subParent(thisPtr);
+    }
 
+     addRefCP(pImage);
      subRefCP(_sfImage.getValue());
 
     _sfImage.setValue(pImage);
+    
+    if(_sfImage.getValue() != NullFC)
+    {
+        TextureChunkPtr thisPtr(*this);
+        
+        _sfImage.getValue()->addParent(thisPtr);
+    }
 }
 
 /*! Utility function to be called whenever the contents of the image change. 
@@ -148,6 +169,23 @@
     getShaderOffsetMatrix()[3] = m22;
 }
 
+inline void
+TextureChunk::triggerRefresh(void)
+{
+    if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
+    {
+        Window::refreshGLObject(getGLId());
+    }
+}
+
+inline void
+TextureChunk::triggerReInit(void)
+{
+    if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
+    {
+        Window::reinitializeGLObject(getGLId());
+    }
+}
 
 OSG_END_NAMESPACE
 
#include <OSGGLUT.h>
#include <OSGGLEXT.h>
#include <OSGConfig.h>
#include <OSGTime.h>
#include <OSGSimpleGeometry.h>
#include <OSGPassiveWindow.h>
#include <OSGSimpleSceneManager.h>
#include <OSGSceneFileHandler.h>

#include <OSGSimpleMaterial.h>
#include <OSGTextureChunk.h>
#include <OSGImage.h>
#include <OSGTexGenChunk.h>
#include <OSGTextureTransformChunk.h>


OSG_USING_NAMESPACE

SimpleSceneManager *mgr;

const UInt16 p1size = 128;
const UInt16 t1size = 16;

ImagePtr         img1;
TextureChunkPtr  tx1;

// redraw the window
void display(void)
{      
    static Real32 lastTime = 0;
    Real32 time = (getSystemTime() - lastTime);
    lastTime    = getSystemTime();
    
    UInt32 redVal   = osgabs(osgcos(time) * 64 );
    UInt32 greenVal = osgabs(osgcos(time) * 128);
    UInt32 blueVal  = osgabs(osgcos(time) * 255);
    
    beginEditCP(img1, Image::PixelFieldMask);
        UInt8 *img1Data = img1->getData();
        for(UInt16 y = 0; y < p1size; ++y)
        {
            for(UInt16 x = 0; x < p1size; ++x)
            {
                if((x / t1size + y / t1size) & 1)
                {
                    *img1Data++ = 0;
                    *img1Data++ = 0;
                    *img1Data++ = 0;
                }
                else
                {
                    *img1Data++ = redVal;
                    *img1Data++ = greenVal;
                    *img1Data++ = blueVal;
                }
            }
        }
    endEditCP  (img1, Image::PixelFieldMask);
    
    // render    
    mgr->redraw();

    // all done, swap    
    glutSwapBuffers();
}

// react to size changes
void reshape(int w, int h)
{
    mgr->resize(w,h);
    glutPostRedisplay();
}

// react to mouse button presses
void mouse(int button, int state, int x, int y)
{
    if (state)
        mgr->mouseButtonRelease(button, x, y);
    else
        mgr->mouseButtonPress(button, x, y);
        
    glutPostRedisplay();
}

// react to mouse motions with pressed buttons
void motion(int x, int y)
{
    mgr->mouseMove(x, y);
    glutPostRedisplay();
}

// react to keys
void keyboard(unsigned char k, int, int)
{
    switch(k)
    {

    case 27:    osgExit();
                exit(1);
    }
}


int main(int argc, char **argv)
{
    osgInit(argc,argv);

    // GLUT init
    glutInit(&argc, argv);
    
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    
    glutCreateWindow("OpenSG");
    
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);

    PassiveWindowPtr pwin=PassiveWindow::create();
    pwin->init();   
    
    // create the two textures
    tx1 = TextureChunk::create();
       
    img1 = Image::create();
    img1->set(Image::OSG_RGB_PF, p1size, p1size );
    
    beginEditCP(img1);
        UInt8 *img1Data = img1->getData();
    
        for(UInt16 y = 0; y < p1size; ++y)
        {
            for(UInt16 x = 0; x < p1size; ++x)
            {
                if((x / t1size + y / t1size) & 1)
                {
                    *img1Data++ = 0;
                    *img1Data++ = 0;
                    *img1Data++ = 0;
                }
                else
                {
                    *img1Data++ = 64;
                    *img1Data++ = 128;
                    *img1Data++ = 255;
                }
            }
        }
    endEditCP(img1);
    
    beginEditCP(tx1);
        tx1->setImage(img1); 
        tx1->setMinFilter(GL_LINEAR);
        tx1->setMagFilter(GL_LINEAR);
        tx1->setWrapS(GL_REPEAT);
        tx1->setWrapT(GL_REPEAT);
    endEditCP(tx1);
   
    // create the material
    SimpleMaterialPtr mat = SimpleMaterial::create();
    
    beginEditCP(mat);
    mat->setDiffuse(Color3f(1,1,1));
    mat->setLit(false);
    mat->addChunk(tx1);
    endEditCP(mat);
    
    // create the scene
    NodePtr scene;
    
    scene = Node::create();
    GeometryPtr g1 = Geometry::create();

    beginEditCP(scene);
    scene->setCore(g1);
    endEditCP(scene);

    beginEditCP(g1);

    GeoPositions3fPtr pnts = GeoPositions3f::create();
    g1->setPositions(pnts);

    MFPnt3f* p = pnts->getFieldPtr();

    beginEditCP(pnts);
    p->push_back(Pnt3f(-1, -1, -1));
    p->push_back(Pnt3f( 1, -1, -1));
    p->push_back(Pnt3f( 1,  1, -1));
    p->push_back(Pnt3f(-1,  1, -1));
    p->push_back(Pnt3f(-1, -1,  1));
    p->push_back(Pnt3f( 1, -1,  1));
    p->push_back(Pnt3f( 1,  1,  1));
    p->push_back(Pnt3f(-1,  1,  1));
    endEditCP(pnts);


    GeoNormals3fPtr norms = GeoNormals3f::create();
    g1->setNormals(norms);
    beginEditCP(norms);
    norms->push_back(Vec3f(-1, -1, -1));
    norms->push_back(Vec3f( 1, -1, -1));
    norms->push_back(Vec3f( 1,  1, -1));
    norms->push_back(Vec3f(-1,  1, -1));
    norms->push_back(Vec3f(-1, -1,  1));
    norms->push_back(Vec3f( 1, -1,  1));
    norms->push_back(Vec3f( 1,  1,  1));
    norms->push_back(Vec3f(-1,  1,  1));
    endEditCP(norms);

    GeoTexCoords2fPtr texs = GeoTexCoords2f::create();
    g1->setTexCoords(texs);
    beginEditCP(texs);
    texs->push_back(Vec2f(0, 0));
    texs->push_back(Vec2f(1, 0));
    texs->push_back(Vec2f(1, 1));
    texs->push_back(Vec2f(0, 1));
    texs->push_back(Vec2f(0, 0));
    texs->push_back(Vec2f(2, 0));
    texs->push_back(Vec2f(2, 2));
    texs->push_back(Vec2f(0, 2));
    endEditCP(texs);

    g1->setTexCoords1(texs);

    GeoPLengthsPtr lens = GeoPLengthsUI32::create();    
    g1->setLengths(lens);
    beginEditCP(lens);
    lens->push_back(8);
    endEditCP(lens);

    GeoPTypesPtr type = GeoPTypesUI8::create();     
    g1->setTypes(type);
    beginEditCP(type);
    type->push_back(GL_QUADS);
    endEditCP(type);

    g1->setMaterial(mat);
    
    endEditCP(g1);

    // create the SimpleSceneManager helper
    mgr = new SimpleSceneManager;

    // create the window and initial camera/viewport
    mgr->setWindow(pwin );
    // tell the manager what to manage
    mgr->setRoot  (scene);
    
    // show the whole scene
    mgr->showAll();
    mgr->redraw();
    
    // GLUT main loop
    glutMainLoop();

    return 0;
}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to