Possible bug in SplattingManager::saveMapToImage()


18-12-2008 22:50:25


Calling SplattingManager::saveMapToImage() doesn't actually copy the coverage map into the given image. Instead, it makes the data pointer inside the image point to the coverage map in memory.

Therefore, if I do something like this...

Ogre::Image splatmap;
mSplatMgr->saveMapToImage(0, splatmap);

...I would expect my newly-created "saved" copy to stay the same even if the coverage map is changed, but it does not -- since the data was never actually copied and all I have is a pointer, any subsequent painting also alters all copies.

Is this the desired functionality? If so, it might be better to rename saveMapToImage() to be something more like getMapDataPointer(). Personally, I'd rather have a function that does an actual copy.


19-12-2008 16:36:37

The primary reason the function exists was to be able to save the coverage maps to disk, by acquiring an image and using the image's save method. It works fine for that.
But you're right, it's not helpful if you do indeed want to use the image in any other way than to (immediately) save its contents to disk, and it's not what the function suggests it does. You could change the function by making a copy of mData before the call to "loadDynamicImage".

The problem will be gone in ETL v3. Due to the different way that ETL works with textures I have to make a copy of the data, anyway, to get it to the Image object.


19-12-2008 16:44:32

Right, I've worked around it for now. The code that resulted is a bit ugly, but it works.

Ogre::Image splatmap;
mSplatMgr->saveMapToImage(0, splatmap);

Ogre::Image copy;
copy.loadDynamicImage(reinterpret_cast<unsigned char*>(malloc(splatmap.getSize())), splatmap.getWidth(), splatmap.getHeight(), splatmap.getDepth(), splatmap.getFormat(), false);
memcpy(copy.getData(), splatmap.getData(), splatmap.getSize());