From ebbf2d165360219d1c224f797e1b6eb6dc5e4f15 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 24 Jan 2014 17:31:03 +0000 Subject: [PATCH] From Laurens Voerman, "I experienced a crash in Geometry::fixDeprecatedData(), on certain files, and brought the problem down to a very simple test file, attached as test3.zip. There are two problems: 1> for DrawElementsUShortPrimitiveType (and UInt) the source_pindex still equals -1 and causes a crash in DrawElementsUBytePrimitiveType source_pindex is incremented, and in DrawElementsU(Short/Int)PrimitiveType primitiveNum is incremented, but never used 2> The drawelements need to be rewritten as the vertices are reordered. created a patch for osg stable branch(r14038): attached as Geometry-osg-3.2.zip and for svn brach(r14044): attached as Geometry_osg_svn.zip" --- src/osg/Geometry.cpp | 58 +++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index 1df20446a..ecdc81b81 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -1539,9 +1539,8 @@ void Geometry::fixDeprecatedData() // start the primitiveNum at -1 as we increment it the first time through when // we start processing the primitive sets. - int primitiveNum = -1; int target_vindex = 0; - int source_pindex = -1; + int source_pindex = -1; // equals primitiveNum for(PrimitiveSetList::iterator itr = _primitives.begin(); itr != _primitives.end(); ++itr) @@ -1566,19 +1565,21 @@ void Geometry::fixDeprecatedData() { if (primLength==0) primLength=primitiveset->getNumIndices(); - const DrawArrays* drawArray = static_cast(primitiveset); + DrawArrays* drawArray = static_cast(primitiveset); if (primLength==0) primLength = drawArray->getCount(); unsigned int primCount=0; - unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount(); - for(unsigned int vindex=drawArray->getFirst(); + unsigned int startindex=drawArray->getFirst(); + drawArray->setFirst(target_vindex); + unsigned int indexEnd = startindex+drawArray->getCount(); + for(unsigned int vindex=startindex; vindex(primitiveset); + DrawArrayLengths* drawArrayLengths = static_cast(primitiveset); unsigned int vindex=drawArrayLengths->getFirst(); - for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin(); + for(DrawArrayLengths::iterator primItr=drawArrayLengths->begin(); primItr!=drawArrayLengths->end(); ++primItr) { unsigned int localPrimLength; if (primLength==0) localPrimLength=*primItr; else localPrimLength=primLength; - + drawArrayLengths->setFirst(target_vindex); for(GLsizei primCount=0; primCount<*primItr; ++vindex, ++target_vindex, ++primCount) { if ((primCount%localPrimLength)==0) ++source_pindex; - - // copy bind per primitive from primitiveNum + // copy bind per vertex from vindex for(PtrList::iterator itr = perVertexPtrs.begin(); itr != perVertexPtrs.end(); ++itr) @@ -1640,7 +1640,7 @@ void Geometry::fixDeprecatedData() } } - // copy bind per vertex from vindex + // copy bind per primitive from source_pindex for(PtrList::iterator itr = perPrimitivePtrs.begin(); itr != perPrimitivePtrs.end(); ++itr) @@ -1661,16 +1661,17 @@ void Geometry::fixDeprecatedData() { if (primLength==0) primLength=primitiveset->getNumIndices(); - const DrawElementsUByte* drawElements = static_cast(primitiveset); + DrawElementsUByte* drawElements = static_cast(primitiveset); unsigned int primCount=0; - for(DrawElementsUByte::const_iterator primItr=drawElements->begin(); + for(DrawElementsUByte::iterator primItr=drawElements->begin(); primItr!=drawElements->end(); ++primCount, ++target_vindex, ++primItr) { if ((primCount%primLength)==0) ++source_pindex; unsigned int vindex=*primItr; + *primItr=target_vindex; - // copy bind per primitive from primitiveNum + // copy bind per vertex from vindex for(PtrList::iterator itr = perVertexPtrs.begin(); itr != perVertexPtrs.end(); ++itr) @@ -1684,7 +1685,7 @@ void Geometry::fixDeprecatedData() } } - // copy bind per vertex from vindex + // copy bind per primitive from source_pindex for(PtrList::iterator itr = perPrimitivePtrs.begin(); itr != perPrimitivePtrs.end(); ++itr) @@ -1704,16 +1705,17 @@ void Geometry::fixDeprecatedData() { if (primLength==0) primLength=primitiveset->getNumIndices(); - const DrawElementsUShort* drawElements = static_cast(primitiveset); + DrawElementsUShort* drawElements = static_cast(primitiveset); unsigned int primCount=0; - for(DrawElementsUShort::const_iterator primItr=drawElements->begin(); + for(DrawElementsUShort::iterator primItr=drawElements->begin(); primItr!=drawElements->end(); ++primCount, ++target_vindex, ++primItr) { - if ((primCount%primLength)==0) ++primitiveNum; + if ((primCount%primLength)==0) ++source_pindex; unsigned int vindex=*primItr; + *primItr=target_vindex; - // copy bind per primitive from primitiveNum + // copy bind per vertex from vindex for(PtrList::iterator itr = perVertexPtrs.begin(); itr != perVertexPtrs.end(); ++itr) @@ -1726,8 +1728,7 @@ void Geometry::fixDeprecatedData() *target++ = *source++; } } - - // copy bind per vertex from vindex + // copy bind per primitive from source_pindex for(PtrList::iterator itr = perPrimitivePtrs.begin(); itr != perPrimitivePtrs.end(); ++itr) @@ -1747,16 +1748,17 @@ void Geometry::fixDeprecatedData() { if (primLength==0) primLength=primitiveset->getNumIndices(); - const DrawElementsUInt* drawElements = static_cast(primitiveset); + DrawElementsUInt* drawElements = static_cast(primitiveset); unsigned int primCount=0; - for(DrawElementsUInt::const_iterator primItr=drawElements->begin(); + for(DrawElementsUInt::iterator primItr=drawElements->begin(); primItr!=drawElements->end(); ++primCount, ++target_vindex, ++primItr) { - if ((primCount%primLength)==0) ++primitiveNum; + if ((primCount%primLength)==0) ++source_pindex; unsigned int vindex=*primItr; + *primItr=target_vindex; - // copy bind per primitive from primitiveNum + // copy bind per vertex from vindex for(PtrList::iterator itr = perVertexPtrs.begin(); itr != perVertexPtrs.end(); ++itr) @@ -1770,7 +1772,7 @@ void Geometry::fixDeprecatedData() } } - // copy bind per vertex from vindex + // copy bind per primitive from source_pindex for(PtrList::iterator itr = perPrimitivePtrs.begin(); itr != perPrimitivePtrs.end(); ++itr)