Moved the Array::AttribDivisor into the Array::Binding enum to avoid conflicts in settings between Binding and AttribDivisor.

Removed the vertify bindings/shared arrays handling from GeometryNew
This commit is contained in:
Robert Osfield
2013-06-05 07:27:35 +00:00
parent eb693f6a92
commit 4f1e6b28e8
3 changed files with 15 additions and 525 deletions

View File

@@ -769,14 +769,6 @@ void GeometryNew::compileGLObjects(RenderInfo& renderInfo) const
void GeometryNew::drawImplementation(RenderInfo& renderInfo) const
{
#if 0
if (!validGeometryNew())
{
OSG_NOTICE<<"Error, osg::Geometry has invalid array/primitive set usage"<<std::endl;
return;
}
#endif
State& state = *renderInfo.getState();
bool checkForGLErrors = state.getCheckForGLErrors()==osg::State::ONCE_PER_ATTRIBUTE;
@@ -1107,493 +1099,6 @@ void GeometryNew::accept(PrimitiveIndexFunctor& functor) const
}
}
unsigned int _computeNumberOfPrimitives(const osg::GeometryNew& geom)
{
unsigned int totalNumberOfPrimitives = 0;
for(GeometryNew::PrimitiveSetList::const_iterator itr=geom.getPrimitiveSetList().begin();
itr!=geom.getPrimitiveSetList().end();
++itr)
{
const PrimitiveSet* primitiveset = itr->get();
GLenum mode=primitiveset->getMode();
unsigned int primLength;
switch(mode)
{
case(GL_POINTS): primLength=1; OSG_INFO<<"prim=GL_POINTS"<<std::endl; break;
case(GL_LINES): primLength=2; OSG_INFO<<"prim=GL_LINES"<<std::endl; break;
case(GL_TRIANGLES): primLength=3; OSG_INFO<<"prim=GL_TRIANGLES"<<std::endl; break;
case(GL_QUADS): primLength=4; OSG_INFO<<"prim=GL_QUADS"<<std::endl; break;
default: primLength=0; OSG_INFO<<"prim="<<std::hex<<mode<<std::dec<<std::endl; break; // compute later when =0.
}
// draw primitives by the more flexible "slow" path,
// sending OpenGL Begin/glVertex.../End().
switch(primitiveset->getType())
{
case(PrimitiveSet::DrawArrayLengthsPrimitiveType):
{
const DrawArrayLengths* drawArrayLengths = static_cast<const DrawArrayLengths*>(primitiveset);
for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin();
primItr!=drawArrayLengths->end();
++primItr)
{
if (primLength==0) totalNumberOfPrimitives += 1;
else totalNumberOfPrimitives += *primItr/primLength;
}
break;
}
default:
{
if (primLength==0) { totalNumberOfPrimitives += 1; OSG_INFO<<" totalNumberOfPrimitives="<<totalNumberOfPrimitives<<std::endl;}
else { totalNumberOfPrimitives += primitiveset->getNumIndices()/primLength; OSG_INFO<<" primitiveset->getNumIndices()="<<primitiveset->getNumIndices()<<" totalNumberOfPrimitives="<<totalNumberOfPrimitives<<std::endl; }
}
}
}
return totalNumberOfPrimitives;
}
template<class A>
bool _verifyBindings(const osg::GeometryNew& geom, const A& array)
{
unsigned int numElements = array.valid()?array->getNumElements():0;
switch(array->getBinding())
{
case(osg::Array::BIND_OFF):
if (numElements>0) return false;
break;
case(osg::Array::BIND_OVERALL):
if (numElements!=1) return false;
break;
case(osg::Array::BIND_PER_PRIMITIVE_SET):
if (numElements!=geom.getPrimitiveSetList().size()) return false;
break;
case(osg::Array::BIND_PER_VERTEX):
{
unsigned int numVertices = geom.getVertexArray()?geom.getVertexArray()->getNumElements():0;
if (numElements!=numVertices) return false;
break;
}
case(osg::Array::BIND_AUTO):
{
return true;
}
}
return true;
}
template<class A>
void _computeCorrectBindingsAndArraySizes(std::ostream& out, const osg::GeometryNew& geom, A& array, const char* arrayName)
{
unsigned int numElements = array.valid()?array->getNumElements():0;
// check to see if binding matches 0 elements required.
if (numElements==0)
{
// correct binding if not correct.
if (array->getBinding()!=osg::Array::BIND_OFF)
{
out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() "<<std::endl
<<" "<<arrayName<<" binding has been reset to BIND_OFF"<<std::endl;
array->setBinding(osg::Array::BIND_OFF);
}
return;
}
// check to see if binding matches 1 elements required.
if (numElements==1)
{
// correct binding if not correct.
if (array->getBinding()!=osg::Array::BIND_OVERALL)
{
out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() "<<std::endl
<<" "<<arrayName<<" binding has been reset to BIND_OVERALL"<<std::endl;
array->setBinding(osg::Array::BIND_OVERALL);
}
return;
}
unsigned int numVertices = geom.getVertexArray()?geom.getVertexArray()->getNumElements():0;
if ( numVertices==0 )
{
if (array->getBinding()!=osg::Array::BIND_OFF)
{
array = 0;
out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() vertex array is empty but "<<std::endl
<<" vertex array is empty but"<<arrayName<<" is set"<<std::endl
<<" reseting "<<arrayName<< " binding to BIND_OFF and array & 0."<<std::endl;
}
}
if (numElements==numVertices)
{
// correct the binding to per vertex.
if (array->getBinding()!=osg::Array::BIND_PER_VERTEX)
{
out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() "<<std::endl
<<" "<<arrayName<<" binding has been reset to BIND_PER_VERTEX"<<std::endl;
array->setBinding(osg::Array::BIND_PER_VERTEX);
}
return;
}
// check to see if binding might be per primitive set
unsigned int numPrimitiveSets = geom.getPrimitiveSetList().size();
if (numElements==numPrimitiveSets)
{
if (array->getBinding() != osg::Array::BIND_PER_PRIMITIVE_SET)
{
out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() "<<std::endl
<<" "<<arrayName<<" binding has been reset to BIND_PER_PRIMITIVE_SET"<<std::endl;
array->setBinding(osg::Array::BIND_PER_PRIMITIVE_SET);
}
return;
}
if (numElements>=numVertices)
{
array->setBinding(osg::Array::BIND_PER_VERTEX);
return;
}
if (numElements>=numPrimitiveSets)
{
array->setBinding(osg::Array::BIND_PER_PRIMITIVE_SET);
return;
}
if (numElements>=1)
{
array->setBinding(osg::Array::BIND_OVERALL);
return;
}
array = 0;
}
bool GeometryNew::verifyBindings(const osg::ref_ptr<Array>& array) const
{
return _verifyBindings(*this, array);
}
bool GeometryNew::verifyBindings() const
{
if (!verifyBindings(_normalArray)) return false;
if (!verifyBindings(_colorArray)) return false;
if (!verifyBindings(_secondaryColorArray)) return false;
if (!verifyBindings(_fogCoordArray)) return false;
for(ArrayList::const_iterator titr=_texCoordList.begin();
titr!=_texCoordList.end();
++titr)
{
if (!verifyBindings(*titr)) return false;
}
for(ArrayList::const_iterator vitr=_vertexAttribList.begin();
vitr!=_vertexAttribList.end();
++vitr)
{
if (!verifyBindings(*vitr)) return false;
}
return true;
}
void GeometryNew::computeCorrectBindingsAndArraySizes(osg::ref_ptr<Array>& array,const char* arrayName)
{
return _computeCorrectBindingsAndArraySizes(osg::notify(osg::INFO), *this, array, arrayName);
}
void GeometryNew::computeCorrectBindingsAndArraySizes()
{
// if (verifyBindings()) return;
computeCorrectBindingsAndArraySizes(_normalArray,"_normalArray");
computeCorrectBindingsAndArraySizes(_colorArray,"_colorArray");
computeCorrectBindingsAndArraySizes(_secondaryColorArray,"_secondaryColorArray");
computeCorrectBindingsAndArraySizes(_fogCoordArray,"_fogCoordArray");
for(ArrayList::iterator titr=_texCoordList.begin();
titr!=_texCoordList.end();
++titr)
{
computeCorrectBindingsAndArraySizes(*titr,"_texCoordList[]");
}
for(ArrayList::iterator vitr=_vertexAttribList.begin();
vitr!=_vertexAttribList.end();
++vitr)
{
computeCorrectBindingsAndArraySizes(*vitr,"_vertAttribList[]");
}
}
bool GeometryNew::containsSharedArrays() const
{
unsigned int numSharedArrays = 0;
if (getVertexArray() && getVertexArray()->referenceCount()>1) ++numSharedArrays;
if (getNormalArray() && getNormalArray()->referenceCount()>1) ++numSharedArrays;
if (getColorArray() && getColorArray()->referenceCount()>1) ++numSharedArrays;
if (getSecondaryColorArray() && getSecondaryColorArray()->referenceCount()>1) ++numSharedArrays;
if (getFogCoordArray() && getFogCoordArray()->referenceCount()>1) ++numSharedArrays;
for(unsigned int ti=0;ti<getNumTexCoordArrays();++ti)
{
if (getTexCoordArray(ti) && getTexCoordArray(ti)->referenceCount()>1) ++numSharedArrays;
}
for(unsigned int vi=0;vi<_vertexAttribList.size();++vi)
{
const Array* array = _vertexAttribList[vi].get();
if (array && array->referenceCount()>1) ++numSharedArrays;
}
return numSharedArrays!=0;
}
void GeometryNew::duplicateSharedArrays()
{
#define DUPLICATE_IF_REQUIRED(A) \
if (get##A() && get##A()->referenceCount()>1) \
{ \
set##A(osg::clone(get##A(), osg::CopyOp::DEEP_COPY_ARRAYS)); \
}
DUPLICATE_IF_REQUIRED(VertexArray)
DUPLICATE_IF_REQUIRED(NormalArray)
DUPLICATE_IF_REQUIRED(ColorArray)
DUPLICATE_IF_REQUIRED(SecondaryColorArray)
DUPLICATE_IF_REQUIRED(FogCoordArray)
for(unsigned int ti=0;ti<getNumTexCoordArrays();++ti)
{
if (getTexCoordArray(ti) && getTexCoordArray(ti)->referenceCount()>1)
{
setTexCoordArray(ti, osg::clone(getTexCoordArray(ti),osg::CopyOp::DEEP_COPY_ARRAYS));
}
}
for(unsigned int vi=0;vi<_vertexAttribList.size();++vi)
{
Array* array = _vertexAttribList[vi].get();
if (array && array->referenceCount()>1)
{
_vertexAttribList[vi] = osg::clone(array, osg::CopyOp::DEEP_COPY_ARRAYS);
}
}
}
class CheckArrayValidity
{
public:
CheckArrayValidity(const osg::GeometryNew* geometry)
{
numPrimitiveSets = geometry->getNumPrimitiveSets();
primitiveNum = 0;
maxVertexNumber = 0;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// draw the primitives themselves.
//
for(unsigned int primitiveSetNum=0; primitiveSetNum != numPrimitiveSets; ++primitiveSetNum)
{
const PrimitiveSet* primitiveset = geometry->getPrimitiveSet(primitiveSetNum);
GLenum mode=primitiveset->getMode();
unsigned int primLength;
switch(mode)
{
case(GL_POINTS): primLength=1; break;
case(GL_LINES): primLength=2; break;
case(GL_TRIANGLES): primLength=3; break;
case(GL_QUADS): primLength=4; break;
default: primLength=0; break; // compute later when =0.
}
// draw primitives by the more flexible "slow" path,
// sending OpenGL glBegin/glVertex.../glEnd().
switch(primitiveset->getType())
{
case(PrimitiveSet::DrawArraysPrimitiveType):
{
if (primLength==0) primLength=primitiveset->getNumIndices();
const DrawArrays* drawArray = static_cast<const DrawArrays*>(primitiveset);
unsigned int primCount=0;
unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount();
for(unsigned int vindex=drawArray->getFirst();
vindex<indexEnd;
++vindex,++primCount)
{
if ((primCount%primLength)==0)
{
primitiveNum++;
}
}
if ((indexEnd-1) > maxVertexNumber) maxVertexNumber = (indexEnd-1);
break;
}
case(PrimitiveSet::DrawArrayLengthsPrimitiveType):
{
const DrawArrayLengths* drawArrayLengths = static_cast<const DrawArrayLengths*>(primitiveset);
unsigned int vindex=drawArrayLengths->getFirst();
for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin();
primItr!=drawArrayLengths->end();
++primItr)
{
unsigned int localPrimLength;
if (primLength==0) localPrimLength=*primItr;
else localPrimLength=primLength;
for(GLsizei primCount=0;
primCount<*primItr;
++vindex,++primCount)
{
if ((primCount%localPrimLength)==0)
{
primitiveNum++;
}
}
}
if ((vindex-1) > maxVertexNumber) maxVertexNumber = (vindex-1);
break;
}
case(PrimitiveSet::DrawElementsUBytePrimitiveType):
{
if (primLength==0) primLength=primitiveset->getNumIndices();
const DrawElementsUByte* drawElements = static_cast<const DrawElementsUByte*>(primitiveset);
unsigned int primCount=0;
for(DrawElementsUByte::const_iterator primItr=drawElements->begin();
primItr!=drawElements->end();
++primCount,++primItr)
{
if ((primCount%primLength)==0)
{
primitiveNum++;
}
unsigned int vindex = *primItr;
if (vindex > maxVertexNumber) maxVertexNumber = vindex;
}
break;
}
case(PrimitiveSet::DrawElementsUShortPrimitiveType):
{
if (primLength==0) primLength=primitiveset->getNumIndices();
const DrawElementsUShort* drawElements = static_cast<const DrawElementsUShort*>(primitiveset);
unsigned int primCount=0;
for(DrawElementsUShort::const_iterator primItr=drawElements->begin();
primItr!=drawElements->end();
++primCount,++primItr)
{
if ((primCount%primLength)==0)
{
primitiveNum++;
}
unsigned int vindex = *primItr;
if (vindex > maxVertexNumber) maxVertexNumber = vindex;
}
break;
}
case(PrimitiveSet::DrawElementsUIntPrimitiveType):
{
if (primLength==0) primLength=primitiveset->getNumIndices();
const DrawElementsUInt* drawElements = static_cast<const DrawElementsUInt*>(primitiveset);
unsigned int primCount=0;
for(DrawElementsUInt::const_iterator primItr=drawElements->begin();
primItr!=drawElements->end();
++primCount,++primItr)
{
if ((primCount%primLength)==0)
{
primitiveNum++;
}
unsigned int vindex = *primItr;
if (vindex > maxVertexNumber) maxVertexNumber = vindex;
}
break;
}
default:
{
break;
}
}
}
}
bool validArray(std::ostream& out, const osg::Array* array, const char* arrayName)
{
unsigned int numRequired = 0;
switch(array->getBinding())
{
case(osg::Array::BIND_OFF): numRequired = 0; break;
case(osg::Array::BIND_OVERALL): numRequired = 1; break;
case(osg::Array::BIND_PER_PRIMITIVE_SET): numRequired = numPrimitiveSets; break;
case(osg::Array::BIND_PER_VERTEX): numRequired = maxVertexNumber+1; break;
case(osg::Array::BIND_AUTO): numRequired = maxVertexNumber+1; break;
}
{
unsigned int numElements = array ? array->getNumElements() : 0;
if (numElements<numRequired)
{
out<<"Not enough "<<arrayName<<", numRequired="<<numRequired<<", but number in array="<<numElements<<std::endl;
return false;
}
}
return true;
}
unsigned int numPrimitiveSets;
unsigned int primitiveNum;
unsigned int maxVertexNumber;
};
bool GeometryNew::verifyArrays(std::ostream& out) const
{
CheckArrayValidity cav(this);
bool result = true;
if (!cav.validArray(out, _vertexArray.get(), "Vertex")) result = false;
if (!cav.validArray(out, _normalArray.get(), "Normal")) result = false;
if (!cav.validArray(out, _colorArray.get(), "Color")) result = false;
if (!cav.validArray(out, _secondaryColorArray.get(), "SecondaryColor")) result = false;
if (!cav.validArray(out, _fogCoordArray.get(), "FogCoord")) result = false;
for(unsigned int ti=0;ti<_texCoordList.size();++ti)
{
if (!cav.validArray(out, _texCoordList[ti].get(), "TexCoord")) result = false;
}
for(unsigned int vi=0;vi<_vertexAttribList.size();++vi)
{
if (!cav.validArray(out, _vertexAttribList[vi].get(), "TexCoord")) result = false;
}
return result;
}
GeometryNew* osg::createTexturedQuadGeometryNew(const Vec3& corner,const Vec3& widthVec,const Vec3& heightVec, float l, float b, float r, float t)
{
GeometryNew* geom = new GeometryNew;