From 5292c7ca50cb619f122ebf855a268661ffe26631 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 24 Jan 2014 17:31:09 +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 072832c14..eda8603dd 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -1553,9 +1553,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) @@ -1580,19 +1579,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) @@ -1654,7 +1654,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) @@ -1675,16 +1675,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) @@ -1698,7 +1699,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) @@ -1718,16 +1719,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) @@ -1740,8 +1742,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) @@ -1761,16 +1762,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) @@ -1784,7 +1786,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)