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