From Farshid Lashkari, "I recently encountered an issue attempting to load an IVE file generated by an older version of OSG. The file contained dxt1 compressed image data with mipmaps. The loaded model would cause crashes when passing the mipmap data to glCompressedTexImage2D. It seems that the size of the data array within the IVE file did not match the computed size from Image::getTotalSizeInBytesIncludingMipmaps(). This essentially made the mipmap offsets invalid within the Image object.

I'm not sure if the IVE was simply generated incorrectly, or if the Image::getTotalSizeInBytesIncludingMipmaps() was modified since the file was generated. Either way, I added a simple check in the IVE loader so that it clears the mipmap offsets if the actual data size does not match the computed data size. This seems like a safe fallback since the mipmap data can be automatically generated, and it fixes the problem in my case.

Also, while looking into this issue, I noticed that the osgDB::InputStream class applies the serialized image allocation mode. However, since the serializer is allocating the image data itself, it seems like it should force the allocation mode to USE_NEW_DELETE.
"
This commit is contained in:
Robert Osfield 2013-11-21 13:59:00 +00:00
parent 1e2bead9bc
commit a5d78953d4
2 changed files with 9 additions and 2 deletions

View File

@ -684,7 +684,7 @@ osg::Image* InputStream::readImage(bool readFromExternal)
image = new osg::Image; image = new osg::Image;
image->setOrigin( (osg::Image::Origin)origin ); image->setOrigin( (osg::Image::Origin)origin );
image->setImage( s, t, r, internalFormat, pixelFormat, dataType, image->setImage( s, t, r, internalFormat, pixelFormat, dataType,
(unsigned char*)data, (osg::Image::AllocationMode)mode, packing ); (unsigned char*)data, osg::Image::USE_NEW_DELETE, packing );
} }
// _mipmapData // _mipmapData

View File

@ -133,9 +133,10 @@ void Image::read(DataInputStream* in)
// Read image data if any // Read image data if any
unsigned int dataSize = 0;
if(in->readBool()) if(in->readBool())
{ {
unsigned int dataSize = (unsigned int)in->readInt(); dataSize = (unsigned int)in->readInt();
//static int totalSize = 0; //static int totalSize = 0;
@ -154,6 +155,12 @@ void Image::read(DataInputStream* in)
} }
_mipmapData.swap(mipmapData); _mipmapData.swap(mipmapData);
// If data size does not match computed image size, then clear mipmaps since we probably have invalid offsets
if (dataSize > 0 && dataSize != getTotalSizeInBytesIncludingMipmaps())
{
_mipmapData.clear();
}
} }
else{ else{
in_THROW_EXCEPTION("Image::read(): Expected Image identification."); in_THROW_EXCEPTION("Image::read(): Expected Image identification.");