diff --git a/include/osg/Array b/include/osg/Array index af41564ae..36eec5f91 100644 --- a/include/osg/Array +++ b/include/osg/Array @@ -76,16 +76,33 @@ class OSG_EXPORT Array : public BufferData MatrixArrayType = 22 }; + enum Binding + { + BIND_OFF=0, + BIND_OVERALL=1, + BIND_PER_PRIMITIVE_SET=2, + BIND_PER_VERTEX=4, + BIND_AUTO=5 + }; + Array(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0): _arrayType(arrayType), _dataSize(dataSize), - _dataType(dataType) {} + _dataType(dataType), + _normalize(false), + _preserveDataType(false), + _attribDivisor(false), + _binding(BIND_AUTO) {} Array(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): BufferData(array,copyop), _arrayType(array._arrayType), _dataSize(array._dataSize), - _dataType(array._dataType) {} + _dataType(array._dataType), + _normalize(array._normalize), + _preserveDataType(array._preserveDataType), + _attribDivisor(array._attribDivisor), + _binding(array._binding) {} virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } virtual const char* libraryName() const { return "osg"; } @@ -123,28 +140,18 @@ class OSG_EXPORT Array : public BufferData /** Get hint to ask that the array data is passed via integer or double, or normal setVertexAttribPointer function.*/ bool getPreserveDataType() const { return _preserveDataType; } - /** Set the rate at which generic vertex attributes advance during instanced rendering. Uses the glVertexAttribDivisor feature of OpenGL 4.0*/ void setAttribDivisor(GLuint divisor) { _attribDivisor = divisor; } - /** Get the rate at which generic vertex attributes advance during instanced rendering.*/ GLuint getAttribDivisor() const { return _attribDivisor; } - enum Binding - { - BIND_OFF=0, - BIND_OVERALL, - BIND_PER_PRIMITIVE_SET, - BIND_PER_VERTEX - }; - /** Specify how this array should be passed to OpenGL.*/ void setBinding(Binding binding) { _binding = binding; } /** Get how this array should be passed to OpenGL.*/ Binding getBinding() const { return _binding; } - + /** Frees unused space on this vector - i.e. the difference between size() and max_size() of the underlying vector.*/ virtual void trim() {} diff --git a/include/osg/ArrayDispatchers b/include/osg/ArrayDispatchers index 4322fc8ba..8120f5f07 100644 --- a/include/osg/ArrayDispatchers +++ b/include/osg/ArrayDispatchers @@ -41,19 +41,8 @@ class OSG_EXPORT ArrayDispatchers : public osg::Referenced void setState(osg::State* state); - AttributeDispatch* vertexDispatcher(Array* array, IndexArray* indices); - AttributeDispatch* normalDispatcher(Array* array, IndexArray* indices); - AttributeDispatch* colorDispatcher(Array* array, IndexArray* indices); - AttributeDispatch* secondaryColorDispatcher(Array* array, IndexArray* indices); - AttributeDispatch* fogCoordDispatcher(Array* array, IndexArray* indices); - AttributeDispatch* texCoordDispatcher(unsigned int unit, Array* array, IndexArray* indices); - AttributeDispatch* vertexAttribDispatcher(unsigned int unit, Array* array, IndexArray* indices); - void reset(); - void setUseGLBeginEndAdapter(bool flag) { _useGLBeginEndAdapter = flag; } - bool getUseGLBeginEndAdapter() const { return _useGLBeginEndAdapter; } - void setUseVertexAttribAlias(bool flag) { _useVertexAttribAlias = flag; } bool getUseVertexAttribAlias() const { return _useVertexAttribAlias; } @@ -62,6 +51,23 @@ class OSG_EXPORT ArrayDispatchers : public osg::Referenced if (at) _activeDispatchList[binding].push_back(at); } + void activateVertexArray(osg::Array* array) { if (array && array->getBinding()!=osg::Array::BIND_OFF) activate(array->getBinding(), vertexDispatcher(array, 0)); } + void activateColorArray(osg::Array* array) { if (array && array->getBinding()!=osg::Array::BIND_OFF) activate(array->getBinding(), colorDispatcher(array, 0)); } + void activateNormalArray(osg::Array* array) { if (array && array->getBinding()!=osg::Array::BIND_OFF) activate(array->getBinding(), normalDispatcher(array, 0)); } + void activateSecondaryColorArray(osg::Array* array) { if (array && array->getBinding()!=osg::Array::BIND_OFF) activate(array->getBinding(), secondaryColorDispatcher(array, 0)); } + void activateFogCoordArray(osg::Array* array) { if (array && array->getBinding()!=osg::Array::BIND_OFF) activate(array->getBinding(), fogCoordDispatcher(array, 0)); } + void activateTexCoordArray(unsigned int unit, osg::Array* array) { if (array && array->getBinding()!=osg::Array::BIND_OFF) activate(array->getBinding(), texCoordDispatcher(unit, array, 0)); } + void activateVertexAttribArray(unsigned int unit, osg::Array* array) { if (array && array->getBinding()!=osg::Array::BIND_OFF) activate(array->getBinding(), vertexAttribDispatcher(unit, array, 0)); } + + + AttributeDispatch* vertexDispatcher(Array* array, IndexArray* indices); + AttributeDispatch* normalDispatcher(Array* array, IndexArray* indices); + AttributeDispatch* colorDispatcher(Array* array, IndexArray* indices); + AttributeDispatch* secondaryColorDispatcher(Array* array, IndexArray* indices); + AttributeDispatch* fogCoordDispatcher(Array* array, IndexArray* indices); + AttributeDispatch* texCoordDispatcher(unsigned int unit, Array* array, IndexArray* indices); + AttributeDispatch* vertexAttribDispatcher(unsigned int unit, Array* array, IndexArray* indices); + void activateVertexArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { if (binding && array) activate(binding, vertexDispatcher(array, indices)); } void activateColorArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { if (binding && array) activate(binding, colorDispatcher(array, indices)); } void activateNormalArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { if (binding && array) activate(binding, normalDispatcher(array, indices)); } @@ -83,6 +89,10 @@ class OSG_EXPORT ArrayDispatchers : public osg::Referenced bool active(unsigned int binding) const { return !_activeDispatchList[binding].empty(); } + void setUseGLBeginEndAdapter(bool flag) { _useGLBeginEndAdapter = flag; } + bool getUseGLBeginEndAdapter() const { return _useGLBeginEndAdapter; } + + void Begin(GLenum mode) { #ifdef OSG_GL1_AVAILABLE diff --git a/include/osg/GeometryNew b/include/osg/GeometryNew index 21bd98a46..2e69a6f10 100644 --- a/include/osg/GeometryNew +++ b/include/osg/GeometryNew @@ -23,7 +23,6 @@ namespace osg { - class OSG_EXPORT GeometryNew : public Drawable { public: @@ -46,156 +45,62 @@ class OSG_EXPORT GeometryNew : public Drawable bool empty() const; + /** Same values as Array::Binding.*/ enum AttributeBinding { BIND_OFF=0, - BIND_OVERALL, - BIND_PER_PRIMITIVE_SET, - BIND_PER_PRIMITIVE, - BIND_PER_VERTEX + BIND_OVERALL=1, + BIND_PER_PRIMITIVE_SET=2, + BIND_PER_PRIMITIVE=3, /// deprecated + BIND_PER_VERTEX=4 }; - struct OSG_EXPORT ArrayData - { - ArrayData(): - binding(BIND_OFF), - normalize(GL_FALSE) {} - - ArrayData(const ArrayData& data,const CopyOp& copyop=CopyOp::SHALLOW_COPY); - - ArrayData(Array* a, AttributeBinding b, GLboolean n = GL_FALSE): - array(a), - binding(b), - normalize(n) {} - - ArrayData(Array* a, IndexArray* i, AttributeBinding b, GLboolean n = GL_FALSE): - array(a), - binding(b), - normalize(n) {} - - ArrayData& operator = (const ArrayData& rhs) - { - array = rhs.array; - binding = rhs.binding; - normalize = rhs.normalize; - return *this; - } - - inline bool empty() const { return !array.valid(); } - - ref_ptr array; - AttributeBinding binding; - GLboolean normalize; - }; - - struct OSG_EXPORT Vec3ArrayData - { - Vec3ArrayData(): - binding(BIND_OFF), - normalize(GL_FALSE) {} - - Vec3ArrayData(const Vec3ArrayData& data,const CopyOp& copyop=CopyOp::SHALLOW_COPY); - - Vec3ArrayData(Vec3Array* a, AttributeBinding b, GLboolean n = GL_FALSE): - array(a), - binding(b), - normalize(n) {} - - Vec3ArrayData(Vec3Array* a, IndexArray* i, AttributeBinding b, GLboolean n = GL_FALSE): - array(a), - binding(b), - normalize(n) {} - - Vec3ArrayData& operator = (const Vec3ArrayData& rhs) - { - array = rhs.array; - binding = rhs.binding; - normalize = rhs.normalize; - return *this; - } - - inline bool empty() const { return !array.valid(); } - - ref_ptr array; - AttributeBinding binding; - GLboolean normalize; - }; - - /** Static ArrayData which is returned from getTexCoordData(i) const and getVertexAttribData(i) const - * when i is out of range. - */ - static const ArrayData s_InvalidArrayData; - - typedef std::vector< ArrayData > ArrayDataList; - + typedef std::vector< osg::ref_ptr > ArrayList; void setVertexArray(Array* array); - Array* getVertexArray() { return _vertexData.array.get(); } - const Array* getVertexArray() const { return _vertexData.array.get(); } - - void setVertexData(const ArrayData& arrayData); - ArrayData& getVertexData() { return _vertexData; } - const ArrayData& getVertexData() const { return _vertexData; } + Array* getVertexArray() { return _vertexArray.get(); } + const Array* getVertexArray() const { return _vertexArray.get(); } void setNormalBinding(AttributeBinding ab); - AttributeBinding getNormalBinding() const { return _normalData.binding; } + AttributeBinding getNormalBinding() const; void setNormalArray(Array* array); - Array* getNormalArray() { return _normalData.array.get(); } - const Array* getNormalArray() const { return _normalData.array.get(); } - - void setNormalData(const ArrayData& arrayData); - ArrayData& getNormalData() { return _normalData; } - const ArrayData& getNormalData() const { return _normalData; } + Array* getNormalArray() { return _normalArray.get(); } + const Array* getNormalArray() const { return _normalArray.get(); } + void setColorBinding(AttributeBinding ab); - AttributeBinding getColorBinding() const { return _colorData.binding; } + AttributeBinding getColorBinding() const; void setColorArray(Array* array); - Array* getColorArray() { return _colorData.array.get(); } - const Array* getColorArray() const { return _colorData.array.get(); } - - void setColorData(const ArrayData& arrayData); - ArrayData& getColorData() { return _colorData; } - const ArrayData& getColorData() const { return _colorData; } + Array* getColorArray() { return _colorArray.get(); } + const Array* getColorArray() const { return _colorArray.get(); } void setSecondaryColorBinding(AttributeBinding ab); - AttributeBinding getSecondaryColorBinding() const { return _secondaryColorData.binding; } + AttributeBinding getSecondaryColorBinding() const; void setSecondaryColorArray(Array* array); - Array* getSecondaryColorArray() { return _secondaryColorData.array.get(); } - const Array* getSecondaryColorArray() const { return _secondaryColorData.array.get(); } - - void setSecondaryColorData(const ArrayData& arrayData); - ArrayData& getSecondaryColorData() { return _secondaryColorData; } - const ArrayData& getSecondaryColorData() const { return _secondaryColorData; } + Array* getSecondaryColorArray() { return _secondaryColorArray.get(); } + const Array* getSecondaryColorArray() const; void setFogCoordBinding(AttributeBinding ab); - AttributeBinding getFogCoordBinding() const { return _fogCoordData.binding; } + AttributeBinding getFogCoordBinding() const; void setFogCoordArray(Array* array); - Array* getFogCoordArray() { return _fogCoordData.array.get(); } - const Array* getFogCoordArray() const { return _fogCoordData.array.get(); } - - void setFogCoordData(const ArrayData& arrayData); - ArrayData& getFogCoordData() { return _fogCoordData; } - const ArrayData& getFogCoordData() const { return _fogCoordData; } + Array* getFogCoordArray() { return _fogCoordArray.get(); } + const Array* getFogCoordArray() const { return _fogCoordArray.get(); } void setTexCoordArray(unsigned int unit,Array*); Array* getTexCoordArray(unsigned int unit); const Array* getTexCoordArray(unsigned int unit) const; - void setTexCoordData(unsigned int index,const ArrayData& arrayData); - ArrayData& getTexCoordData(unsigned int index); - const ArrayData& getTexCoordData(unsigned int index) const; - unsigned int getNumTexCoordArrays() const { return static_cast(_texCoordList.size()); } - ArrayDataList& getTexCoordArrayList() { return _texCoordList; } - const ArrayDataList& getTexCoordArrayList() const { return _texCoordList; } + ArrayList& getTexCoordArrayList() { return _texCoordList; } + const ArrayList& getTexCoordArrayList() const { return _texCoordList; } @@ -209,13 +114,9 @@ class OSG_EXPORT GeometryNew : public Drawable void setVertexAttribNormalize(unsigned int index,GLboolean norm); GLboolean getVertexAttribNormalize(unsigned int index) const; - void setVertexAttribData(unsigned int index,const ArrayData& arrayData); - ArrayData& getVertexAttribData(unsigned int index); - const ArrayData& getVertexAttribData(unsigned int index) const; - unsigned int getNumVertexAttribArrays() const { return static_cast(_vertexAttribList.size()); } - ArrayDataList& getVertexAttribArrayList() { return _vertexAttribList; } - const ArrayDataList& getVertexAttribArrayList() const { return _vertexAttribList; } + ArrayList& getVertexAttribArrayList() { return _vertexAttribList; } + const ArrayList& getVertexAttribArrayList() const { return _vertexAttribList; } @@ -267,38 +168,15 @@ class OSG_EXPORT GeometryNew : public Drawable * for all graphics contexts. */ virtual void releaseGLObjects(State* state=0) const; - typedef std::vector ArrayList; bool getArrayList(ArrayList& arrayList) const; typedef std::vector DrawElementsList; bool getDrawElementsList(DrawElementsList& drawElementsList) const; osg::VertexBufferObject* getOrCreateVertexBufferObject(); - osg::ElementBufferObject* getOrCreateElementBufferObject(); - /** Set whether fast paths should be used when supported. */ - void setFastPathHint(bool on) { _fastPathHint = on; } - - /** Get whether fast paths should be used when supported. */ - bool getFastPathHint() const { return _fastPathHint; } - - - /** Return true if OpenGL fast paths will be used with drawing this Geometry. - * Fast paths directly use vertex arrays, and glDrawArrays/glDrawElements so have low CPU overhead. - * With Slow paths the osg::Geometry::drawImplementation has to dynamically assemble OpenGL - * compatible vertex arrays from the osg::Geometry arrays data and then dispatch these to OpenGL, - * so have higher CPU overhead than the Fast paths. - * Use of per primitive bindings or per vertex indexed arrays will drop the rendering path off the fast path. - */ - inline bool areFastPathsUsed() const - { - return _fastPath && _fastPathHint; - } - - bool computeFastPathsUsed(); - bool verifyBindings() const; void computeCorrectBindingsAndArraySizes(); @@ -359,27 +237,22 @@ class OSG_EXPORT GeometryNew : public Drawable virtual ~GeometryNew(); - bool verifyBindings(const ArrayData& arrayData) const; - bool verifyBindings(const Vec3ArrayData& arrayData) const; + bool verifyBindings(const osg::ref_ptr& array) const; - void computeCorrectBindingsAndArraySizes(ArrayData& arrayData,const char* arrayName); - void computeCorrectBindingsAndArraySizes(Vec3ArrayData& arrayData,const char* arrayName); + void computeCorrectBindingsAndArraySizes(osg::ref_ptr& ,const char* arrayName); void addVertexBufferObjectIfRequired(osg::Array* array); void addElementBufferObjectIfRequired(osg::PrimitiveSet* primitiveSet); PrimitiveSetList _primitives; - ArrayData _vertexData; - ArrayData _normalData; - ArrayData _colorData; - ArrayData _secondaryColorData; - ArrayData _fogCoordData; - ArrayDataList _texCoordList; - ArrayDataList _vertexAttribList; - - mutable bool _fastPath; - bool _fastPathHint; + osg::ref_ptr _vertexArray; + osg::ref_ptr _normalArray; + osg::ref_ptr _colorArray; + osg::ref_ptr _secondaryColorArray; + osg::ref_ptr _fogCoordArray; + ArrayList _texCoordList; + ArrayList _vertexAttribList; }; /** Convenience function to be used for creating quad geometry with texture coords. diff --git a/src/osg/ArrayDispatchers.cpp b/src/osg/ArrayDispatchers.cpp index b8fad399c..ef6ddac81 100644 --- a/src/osg/ArrayDispatchers.cpp +++ b/src/osg/ArrayDispatchers.cpp @@ -465,6 +465,10 @@ void ArrayDispatchers::init() _activeDispatchList.resize(5); } +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// With inidices +// AttributeDispatch* ArrayDispatchers::vertexDispatcher(Array* array, IndexArray* indices) { return _useVertexAttribAlias ? diff --git a/src/osg/GeometryNew.cpp b/src/osg/GeometryNew.cpp index 21453a3cc..62f3418d8 100644 --- a/src/osg/GeometryNew.cpp +++ b/src/osg/GeometryNew.cpp @@ -18,42 +18,19 @@ using namespace osg; -const GeometryNew::ArrayData GeometryNew::s_InvalidArrayData; - -GeometryNew::ArrayData::ArrayData(const ArrayData& data,const CopyOp& copyop): - array(copyop(data.array.get())), - binding(data.binding), - normalize(data.normalize) -{ -} - -GeometryNew::Vec3ArrayData::Vec3ArrayData(const Vec3ArrayData& data,const CopyOp& copyop): - array(dynamic_cast(copyop(data.array.get()))), - binding(data.binding), - normalize(data.normalize) -{ -} - GeometryNew::GeometryNew() { // temporary test // setSupportsDisplayList(false); - - _vertexData.binding = BIND_PER_VERTEX; - - _fastPath = false; - _fastPathHint = true; } GeometryNew::GeometryNew(const GeometryNew& geometry,const CopyOp& copyop): Drawable(geometry,copyop), - _vertexData(geometry._vertexData,copyop), - _normalData(geometry._normalData,copyop), - _colorData(geometry._colorData,copyop), - _secondaryColorData(geometry._secondaryColorData,copyop), - _fogCoordData(geometry._fogCoordData,copyop), - _fastPath(geometry._fastPath), - _fastPathHint(geometry._fastPathHint) + _vertexArray(copyop(geometry._vertexArray.get())), + _normalArray(copyop(geometry._normalArray.get())), + _colorArray(copyop(geometry._colorArray.get())), + _secondaryColorArray(copyop(geometry._secondaryColorArray.get())), + _fogCoordArray(copyop(geometry._fogCoordArray.get())) { // temporary test // setSupportsDisplayList(false); @@ -66,18 +43,18 @@ GeometryNew::GeometryNew(const GeometryNew& geometry,const CopyOp& copyop): if (primitive) _primitives.push_back(primitive); } - for(ArrayDataList::const_iterator titr=geometry._texCoordList.begin(); + for(ArrayList::const_iterator titr=geometry._texCoordList.begin(); titr!=geometry._texCoordList.end(); ++titr) { - _texCoordList.push_back(ArrayData(*titr, copyop)); + _texCoordList.push_back(copyop(titr->get())); } - for(ArrayDataList::const_iterator vitr=geometry._vertexAttribList.begin(); + for(ArrayList::const_iterator vitr=geometry._vertexAttribList.begin(); vitr!=geometry._vertexAttribList.end(); ++vitr) { - _vertexAttribList.push_back(ArrayData(*vitr, copyop)); + _vertexAttribList.push_back(copyop(vitr->get())); } if ((copyop.getCopyFlags() & osg::CopyOp::DEEP_COPY_ARRAYS)) @@ -101,14 +78,16 @@ GeometryNew::~GeometryNew() // no need to delete, all automatically handled by ref_ptr :-) } +#define ARRAY_NOT_EMPTY(array) (array!=0 && array->getNumElements()!=0) + bool GeometryNew::empty() const { if (!_primitives.empty()) return false; - if (!_vertexData.empty()) return false; - if (!_normalData.empty()) return false; - if (!_colorData.empty()) return false; - if (!_secondaryColorData.empty()) return false; - if (!_fogCoordData.empty()) return false; + if (ARRAY_NOT_EMPTY(_vertexArray.get())) return false; + if (ARRAY_NOT_EMPTY(_normalArray.get())) return false; + if (ARRAY_NOT_EMPTY(_colorArray.get())) return false; + if (ARRAY_NOT_EMPTY(_secondaryColorArray.get())) return false; + if (ARRAY_NOT_EMPTY(_fogCoordArray.get())) return false; if (!_texCoordList.empty()) return false; if (!_vertexAttribList.empty()) return false; return true; @@ -116,169 +95,121 @@ bool GeometryNew::empty() const void GeometryNew::setVertexArray(Array* array) { - _vertexData.array = array; - computeFastPathsUsed(); + _vertexArray = array; + dirtyDisplayList(); dirtyBound(); if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array); } -void GeometryNew::setVertexData(const ArrayData& arrayData) -{ - _vertexData = arrayData; - computeFastPathsUsed(); - dirtyDisplayList(); - dirtyBound(); - - if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get()); -} - void GeometryNew::setNormalArray(Array* array) { - _normalData.array = array; - if (!_normalData.array.valid()) _normalData.binding=BIND_OFF; - computeFastPathsUsed(); + _normalArray = array; + dirtyDisplayList(); if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array); } -void GeometryNew::setNormalData(const ArrayData& arrayData) -{ - _normalData = arrayData; - computeFastPathsUsed(); - dirtyDisplayList(); - - if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get()); -} - void GeometryNew::setColorArray(Array* array) { - _colorData.array = array; - if (!_colorData.array.valid()) _colorData.binding=BIND_OFF; - computeFastPathsUsed(); + _colorArray = array; + dirtyDisplayList(); if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array); } -void GeometryNew::setColorData(const ArrayData& arrayData) -{ - _colorData = arrayData; - computeFastPathsUsed(); - dirtyDisplayList(); - - if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get()); -} - - void GeometryNew::setSecondaryColorArray(Array* array) { - _secondaryColorData.array = array; - if (!_secondaryColorData.array.valid()) _secondaryColorData.binding=BIND_OFF; - computeFastPathsUsed(); + _secondaryColorArray = array; + dirtyDisplayList(); if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array); } -void GeometryNew::setSecondaryColorData(const ArrayData& arrayData) -{ - _secondaryColorData = arrayData; - computeFastPathsUsed(); - dirtyDisplayList(); - - if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get()); -} - void GeometryNew::setFogCoordArray(Array* array) { - _fogCoordData.array = array; - if (!_fogCoordData.array.valid()) _fogCoordData.binding=BIND_OFF; - computeFastPathsUsed(); + _fogCoordArray = array; + dirtyDisplayList(); if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array); } -void GeometryNew::setFogCoordData(const ArrayData& arrayData) -{ - _fogCoordData = arrayData; - computeFastPathsUsed(); - dirtyDisplayList(); +#define SET_BINDING(array)\ + if (!array) \ + { \ + OSG_NOTICE<<"Warning, can't assign attribute binding as no has been array assigned to set binding for."<getBinding() == static_cast(ab)) return; \ + array->setBinding(static_cast(ab)); + + +#define GET_BINDING(array) (array!=0 ? static_cast(array->getBinding()) : BIND_OFF) - if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get()); -} void GeometryNew::setNormalBinding(AttributeBinding ab) { - if (_normalData.binding == ab) return; + SET_BINDING(_normalArray.get()) - _normalData.binding = ab; - computeFastPathsUsed(); dirtyDisplayList(); } +GeometryNew::AttributeBinding GeometryNew::getNormalBinding() const +{ + return GET_BINDING(_normalArray.get()); +} + void GeometryNew::setColorBinding(AttributeBinding ab) { - if (_colorData.binding == ab) return; + SET_BINDING(_colorArray.get()) - _colorData.binding = ab; - computeFastPathsUsed(); dirtyDisplayList(); } +GeometryNew::AttributeBinding GeometryNew::getColorBinding() const +{ + return GET_BINDING(_colorArray.get()); +} + void GeometryNew::setSecondaryColorBinding(AttributeBinding ab) { - if (_secondaryColorData.binding == ab) return; + SET_BINDING(_secondaryColorArray.get()) - _secondaryColorData.binding = ab; - computeFastPathsUsed(); dirtyDisplayList(); } +GeometryNew::AttributeBinding GeometryNew::getSecondaryColorBinding() const +{ + return GET_BINDING(_secondaryColorArray.get()); +} + void GeometryNew::setFogCoordBinding(AttributeBinding ab) { - if (_fogCoordData.binding == ab) return; + SET_BINDING(_fogCoordArray.get()) - _fogCoordData.binding = ab; - computeFastPathsUsed(); dirtyDisplayList(); } -void GeometryNew::setTexCoordData(unsigned int unit,const ArrayData& arrayData) +GeometryNew::AttributeBinding GeometryNew::getFogCoordBinding() const { - if (_texCoordList.size()<=unit) - _texCoordList.resize(unit+1); - - _texCoordList[unit] = arrayData; - - if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get()); + return GET_BINDING(_fogCoordArray.get()); } -GeometryNew::ArrayData& GeometryNew::getTexCoordData(unsigned int unit) + +void GeometryNew::setTexCoordArray(unsigned int index,Array* array) { - if (_texCoordList.size()<=unit) - _texCoordList.resize(unit+1); + if (_texCoordList.size()<=index) + _texCoordList.resize(index+1); - return _texCoordList[unit]; -} + _texCoordList[index] = array; -const GeometryNew::ArrayData& GeometryNew::getTexCoordData(unsigned int unit) const -{ - if (_texCoordList.size()<=unit) - return s_InvalidArrayData; + // do we set to array BIND_PER_VERTEX? - return _texCoordList[unit]; -} - -void GeometryNew::setTexCoordArray(unsigned int unit,Array* array) -{ - getTexCoordData(unit).binding = BIND_PER_VERTEX; - getTexCoordData(unit).array = array; - - computeFastPathsUsed(); dirtyDisplayList(); if (_useVertexBufferObjects && array) @@ -287,53 +218,26 @@ void GeometryNew::setTexCoordArray(unsigned int unit,Array* array) } } -Array* GeometryNew::getTexCoordArray(unsigned int unit) +Array* GeometryNew::getTexCoordArray(unsigned int index) { - if (unit<_texCoordList.size()) return _texCoordList[unit].array.get(); + if (index<_texCoordList.size()) return _texCoordList[index].get(); else return 0; } -const Array* GeometryNew::getTexCoordArray(unsigned int unit) const +const Array* GeometryNew::getTexCoordArray(unsigned int index) const { - if (unit<_texCoordList.size()) return _texCoordList[unit].array.get(); + if (index<_texCoordList.size()) return _texCoordList[index].get(); else return 0; } -void GeometryNew::setVertexAttribData(unsigned int index, const GeometryNew::ArrayData& attrData) -{ - if (_vertexAttribList.size()<=index) - _vertexAttribList.resize(index+1); - - _vertexAttribList[index] = attrData; - - computeFastPathsUsed(); - dirtyDisplayList(); - - if (_useVertexBufferObjects && attrData.array.valid()) addVertexBufferObjectIfRequired(attrData.array.get()); -} - -GeometryNew::ArrayData& GeometryNew::getVertexAttribData(unsigned int index) -{ - if (_vertexAttribList.size()<=index) - _vertexAttribList.resize(index+1); - - return _vertexAttribList[index]; -} - -const GeometryNew::ArrayData& GeometryNew::getVertexAttribData(unsigned int index) const -{ - if (_vertexAttribList.size()<=_vertexAttribList.size()) - return s_InvalidArrayData; - - return _vertexAttribList[index]; -} - void GeometryNew::setVertexAttribArray(unsigned int index, Array* array) { - getVertexAttribData(index).array = array; + if (_vertexAttribList.size()<=index) + _vertexAttribList.resize(index+1); + + _vertexAttribList[index] = array; - computeFastPathsUsed(); dirtyDisplayList(); if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array); @@ -341,41 +245,51 @@ void GeometryNew::setVertexAttribArray(unsigned int index, Array* array) Array *GeometryNew::getVertexAttribArray(unsigned int index) { - if (index<_vertexAttribList.size()) return _vertexAttribList[index].array.get(); + if (index<_vertexAttribList.size()) return _vertexAttribList[index].get(); else return 0; } const Array *GeometryNew::getVertexAttribArray(unsigned int index) const { - if (index<_vertexAttribList.size()) return _vertexAttribList[index].array.get(); + if (index<_vertexAttribList.size()) return _vertexAttribList[index].get(); else return 0; } void GeometryNew::setVertexAttribBinding(unsigned int index,AttributeBinding ab) { - if (getVertexAttribData(index).binding == ab) - return; - getVertexAttribData(index).binding = ab; - computeFastPathsUsed(); - dirtyDisplayList(); + if (index<_vertexAttribList.size() && _vertexAttribList[index].valid()) + { + if (_vertexAttribList[index]->getBinding()==static_cast(ab)) return; + + _vertexAttribList[index]->setBinding(static_cast(ab)); + + dirtyDisplayList(); + } + else + { + OSG_NOTICE<<"Warning, can't assign attribute binding as no has been array assigned to set binding for."<(_vertexAttribList[index]->getBinding()); else return BIND_OFF; } void GeometryNew::setVertexAttribNormalize(unsigned int index,GLboolean norm) { - getVertexAttribData(index).normalize = norm; - - dirtyDisplayList(); + if (index<_vertexAttribList.size() && _vertexAttribList[index].valid()) + { + _vertexAttribList[index]->setNormalize(norm); + + dirtyDisplayList(); + } } GLboolean GeometryNew::getVertexAttribNormalize(unsigned int index) const { - if (index<_vertexAttribList.size()) return _vertexAttribList[index].normalize; + if (index<_vertexAttribList.size() && _vertexAttribList[index].valid()) return _vertexAttribList[index]->getNormalize(); else return GL_FALSE; } @@ -483,55 +397,24 @@ unsigned int GeometryNew::getPrimitiveSetIndex(const PrimitiveSet* primitiveset) return _primitives.size(); // node not found. } -bool GeometryNew::computeFastPathsUsed() -{ - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // check to see if fast path can be used. - // - _fastPath = true; - if (_normalData.binding==BIND_PER_PRIMITIVE) _fastPath = false; - else if (_colorData.binding==BIND_PER_PRIMITIVE) _fastPath = false; - else if (_secondaryColorData.binding==BIND_PER_PRIMITIVE) _fastPath = false; - else if (_fogCoordData.binding==BIND_PER_PRIMITIVE) _fastPath = false; - else - { - for( unsigned int va = 0; va < _vertexAttribList.size(); ++va ) - { - if (_vertexAttribList[va].binding==BIND_PER_PRIMITIVE) - { - _fastPath = false; - break; - } - } - } - - _supportsVertexBufferObjects = _fastPath; - - //_supportsVertexBufferObjects = false; - //_useVertexBufferObjects = false; - - return _fastPath; -} - unsigned int GeometryNew::getGLObjectSizeHint() const { unsigned int totalSize = 0; - if (_vertexData.array.valid()) totalSize += _vertexData.array->getTotalDataSize(); + if (_vertexArray.valid()) totalSize += _vertexArray->getTotalDataSize(); - if (_normalData.array.valid()) totalSize += _normalData.array->getTotalDataSize(); + if (_normalArray.valid()) totalSize += _normalArray->getTotalDataSize(); - if (_colorData.array.valid()) totalSize += _colorData.array->getTotalDataSize(); + if (_colorArray.valid()) totalSize += _colorArray->getTotalDataSize(); - if (_secondaryColorData.array.valid()) totalSize += _secondaryColorData.array->getTotalDataSize(); + if (_secondaryColorArray.valid()) totalSize += _secondaryColorArray->getTotalDataSize(); - if (_fogCoordData.array.valid()) totalSize += _fogCoordData.array->getTotalDataSize(); + if (_fogCoordArray.valid()) totalSize += _fogCoordArray->getTotalDataSize(); unsigned int unit; for(unit=0;unit<_texCoordList.size();++unit) { - const Array* array = _texCoordList[unit].array.get(); + const Array* array = _texCoordList[unit].get(); if (array) totalSize += array->getTotalDataSize(); } @@ -542,7 +425,7 @@ unsigned int GeometryNew::getGLObjectSizeHint() const unsigned int index; for( index = 0; index < _vertexAttribList.size(); ++index ) { - const Array* array = _vertexAttribList[index].array.get(); + const Array* array = _vertexAttribList[index].get(); if (array) totalSize += array->getTotalDataSize(); } } @@ -565,21 +448,21 @@ bool GeometryNew::getArrayList(ArrayList& arrayList) const { unsigned int startSize = arrayList.size(); - if (_vertexData.array.valid()) arrayList.push_back(_vertexData.array.get()); - if (_normalData.array.valid()) arrayList.push_back(_normalData.array.get()); - if (_colorData.array.valid()) arrayList.push_back(_colorData.array.get()); - if (_secondaryColorData.array.valid()) arrayList.push_back(_secondaryColorData.array.get()); - if (_fogCoordData.array.valid()) arrayList.push_back(_fogCoordData.array.get()); + if (_vertexArray.valid()) arrayList.push_back(_vertexArray.get()); + if (_normalArray.valid()) arrayList.push_back(_normalArray.get()); + if (_colorArray.valid()) arrayList.push_back(_colorArray.get()); + if (_secondaryColorArray.valid()) arrayList.push_back(_secondaryColorArray.get()); + if (_fogCoordArray.valid()) arrayList.push_back(_fogCoordArray.get()); for(unsigned int unit=0;unit<_texCoordList.size();++unit) { - Array* array = _texCoordList[unit].array.get(); + Array* array = _texCoordList[unit].get(); if (array) arrayList.push_back(array); } for(unsigned int index = 0; index < _vertexAttribList.size(); ++index ) { - Array* array = _vertexAttribList[index].array.get(); + Array* array = _vertexAttribList[index].get(); if (array) arrayList.push_back(array); } @@ -634,7 +517,7 @@ osg::VertexBufferObject* GeometryNew::getOrCreateVertexBufferObject() vitr != arrayList.end(); ++vitr) { - osg::Array* array = *vitr; + osg::Array* array = vitr->get(); if (array->getVertexBufferObject()) return array->getVertexBufferObject(); } @@ -691,7 +574,7 @@ void GeometryNew::setUseVertexBufferObjects(bool flag) vitr != arrayList.end() && !vbo; ++vitr) { - osg::Array* array = *vitr; + osg::Array* array = vitr->get(); if (array->getVertexBufferObject()) vbo = array->getVertexBufferObject(); } @@ -701,7 +584,7 @@ void GeometryNew::setUseVertexBufferObjects(bool flag) vitr != arrayList.end(); ++vitr) { - osg::Array* array = *vitr; + osg::Array* array = vitr->get(); if (!array->getVertexBufferObject()) array->setVertexBufferObject(vbo.get()); } } @@ -738,7 +621,7 @@ void GeometryNew::setUseVertexBufferObjects(bool flag) vitr != arrayList.end(); ++vitr) { - osg::Array* array = *vitr; + osg::Array* array = vitr->get(); if (array->getVertexBufferObject()) array->setVertexBufferObject(0); } @@ -816,8 +699,7 @@ void GeometryNew::compileGLObjects(RenderInfo& renderInfo) const { bool useVertexArrays = _supportsVertexBufferObjects && _useVertexBufferObjects && - renderInfo.getState()->isVertexBufferObjectSupported() && - areFastPathsUsed(); + renderInfo.getState()->isVertexBufferObjectSupported(); if (useVertexArrays) { // OSG_NOTICE<<"GeometryNew::compileGLObjects() use VBO's "<getBufferObject()) bufferObjects.insert(_vertexData.array->getBufferObject()); - if (_normalData.array.valid() && _normalData.array->getBufferObject()) bufferObjects.insert(_normalData.array->getBufferObject()); - if (_colorData.array.valid() && _colorData.array->getBufferObject()) bufferObjects.insert(_colorData.array->getBufferObject()); - if (_secondaryColorData.array.valid() && _secondaryColorData.array->getBufferObject()) bufferObjects.insert(_secondaryColorData.array->getBufferObject()); - if (_fogCoordData.array.valid() && _fogCoordData.array->getBufferObject()) bufferObjects.insert(_fogCoordData.array->getBufferObject()); + if (_vertexArray.valid() && _vertexArray->getBufferObject()) bufferObjects.insert(_vertexArray->getBufferObject()); + if (_normalArray.valid() && _normalArray->getBufferObject()) bufferObjects.insert(_normalArray->getBufferObject()); + if (_colorArray.valid() && _colorArray->getBufferObject()) bufferObjects.insert(_colorArray->getBufferObject()); + if (_secondaryColorArray.valid() && _secondaryColorArray->getBufferObject()) bufferObjects.insert(_secondaryColorArray->getBufferObject()); + if (_fogCoordArray.valid() && _fogCoordArray->getBufferObject()) bufferObjects.insert(_fogCoordArray->getBufferObject()); - for(ArrayDataList::const_iterator itr = _texCoordList.begin(); + for(ArrayList::const_iterator itr = _texCoordList.begin(); itr != _texCoordList.end(); ++itr) { - if (itr->array.valid() && itr->array->getBufferObject()) bufferObjects.insert(itr->array->getBufferObject()); + if (itr->valid() && (*itr)->getBufferObject()) bufferObjects.insert((*itr)->getBufferObject()); } - for(ArrayDataList::const_iterator itr = _vertexAttribList.begin(); + for(ArrayList::const_iterator itr = _vertexAttribList.begin(); itr != _vertexAttribList.end(); ++itr) { - if (itr->array.valid() && itr->array->getBufferObject()) bufferObjects.insert(itr->array->getBufferObject()); + if (itr->valid() && (*itr)->getBufferObject()) bufferObjects.insert((*itr)->getBufferObject()); } for(PrimitiveSetList::const_iterator itr = _primitives.begin(); @@ -900,28 +782,25 @@ void GeometryNew::drawImplementation(RenderInfo& renderInfo) const bool checkForGLErrors = state.getCheckForGLErrors()==osg::State::ONCE_PER_ATTRIBUTE; if (checkForGLErrors) state.checkGLErrors("start of GeometryNew::drawImplementation()"); - bool useFastPath = areFastPathsUsed(); - // useFastPath = false; - bool usingVertexBufferObjects = _useVertexBufferObjects && state.isVertexBufferObjectSupported(); bool handleVertexAttributes = !_vertexAttribList.empty(); ArrayDispatchers& arrayDispatchers = state.getArrayDispatchers(); arrayDispatchers.reset(); - arrayDispatchers.setUseVertexAttribAlias(useFastPath && state.getUseVertexAttributeAliasing()); - arrayDispatchers.setUseGLBeginEndAdapter(!useFastPath); + arrayDispatchers.setUseVertexAttribAlias(state.getUseVertexAttributeAliasing()); + arrayDispatchers.setUseGLBeginEndAdapter(false); - arrayDispatchers.activateNormalArray(_normalData.binding, _normalData.array.get(), 0); - arrayDispatchers.activateColorArray(_colorData.binding, _colorData.array.get(), 0); - arrayDispatchers.activateSecondaryColorArray(_secondaryColorData.binding, _secondaryColorData.array.get(), 0); - arrayDispatchers.activateFogCoordArray(_fogCoordData.binding, _fogCoordData.array.get(), 0); + arrayDispatchers.activateNormalArray(_normalArray.get()); + arrayDispatchers.activateColorArray(_colorArray.get()); + arrayDispatchers.activateSecondaryColorArray(_secondaryColorArray.get()); + arrayDispatchers.activateFogCoordArray(_fogCoordArray.get()); if (handleVertexAttributes) { for(unsigned int unit=0;unit<_vertexAttribList.size();++unit) { - arrayDispatchers.activateVertexAttribArray(_vertexAttribList[unit].binding, unit, _vertexAttribList[unit].array.get(), 0); + arrayDispatchers.activateVertexAttribArray(unit, _vertexAttribList[unit].get()); } } @@ -930,230 +809,58 @@ void GeometryNew::drawImplementation(RenderInfo& renderInfo) const state.lazyDisablingOfVertexAttributes(); - if (useFastPath) + // set up arrays + if( _vertexArray.valid() ) + state.setVertexPointer(_vertexArray.get()); + + if (_normalArray.valid() && _normalArray->getBinding()==osg::Array::BIND_PER_VERTEX) + state.setNormalPointer(_normalArray.get()); + + if (_colorArray.valid() && _colorArray->getBinding()==osg::Array::BIND_PER_VERTEX) + state.setColorPointer(_colorArray.get()); + + if (_secondaryColorArray.valid() && _secondaryColorArray->getBinding()==osg::Array::BIND_PER_VERTEX) + state.setSecondaryColorPointer(_secondaryColorArray.get()); + + if (_fogCoordArray.valid() && _fogCoordArray->getBinding()==osg::Array::BIND_PER_VERTEX) + state.setFogCoordPointer(_fogCoordArray.get()); + + for(unsigned int unit=0;unit<_texCoordList.size();++unit) { - // set up arrays - if( _vertexData.array.valid() ) - state.setVertexPointer(_vertexData.array.get()); + const Array* array = _texCoordList[unit].get(); + if (array) state.setTexCoordPointer(unit,array); + } - if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid()) - state.setNormalPointer(_normalData.array.get()); - - if (_colorData.binding==BIND_PER_VERTEX && _colorData.array.valid()) - state.setColorPointer(_colorData.array.get()); - - if (_secondaryColorData.binding==BIND_PER_VERTEX && _secondaryColorData.array.valid()) - state.setSecondaryColorPointer(_secondaryColorData.array.get()); - - if (_fogCoordData.binding==BIND_PER_VERTEX && _fogCoordData.array.valid()) - state.setFogCoordPointer(_fogCoordData.array.get()); - - for(unsigned int unit=0;unit<_texCoordList.size();++unit) + if( handleVertexAttributes ) + { + for(unsigned int index = 0; index < _vertexAttribList.size(); ++index ) { - const Array* array = _texCoordList[unit].array.get(); - if (array) state.setTexCoordPointer(unit,array); - } - - if( handleVertexAttributes ) - { - for(unsigned int index = 0; index < _vertexAttribList.size(); ++index ) + const Array* array = _vertexAttribList[index].get(); + if(array && array->getBinding()==osg::Array::BIND_PER_VERTEX) { - const Array* array = _vertexAttribList[index].array.get(); - const AttributeBinding ab = _vertexAttribList[index].binding; - if( ab == BIND_PER_VERTEX && array ) - { - state.setVertexAttribPointer( index, array, _vertexAttribList[index].normalize ); - } + state.setVertexAttribPointer( index, array, _vertexAttribList[index]->getNormalize() ); } } } - else - { - for(unsigned int unit=0;unit<_texCoordList.size();++unit) - { - arrayDispatchers.activateTexCoordArray(BIND_PER_VERTEX, unit, _texCoordList[unit].array.get(), 0); - } - - arrayDispatchers.activateVertexArray(BIND_PER_VERTEX, _vertexData.array.get(), 0); - } state.applyDisablingOfVertexAttributes(); bool bindPerPrimitiveSetActive = arrayDispatchers.active(BIND_PER_PRIMITIVE_SET); - bool bindPerPrimitiveActive = arrayDispatchers.active(BIND_PER_PRIMITIVE); - - unsigned int primitiveNum = 0; if (checkForGLErrors) state.checkGLErrors("GeometryNew::drawImplementation() after vertex arrays setup."); - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // draw the primitives themselves. // for(unsigned int primitiveSetNum=0; primitiveSetNum!=_primitives.size(); ++primitiveSetNum) { - // dispatch any attributes that are bound per primitive if (bindPerPrimitiveSetActive) arrayDispatchers.dispatch(BIND_PER_PRIMITIVE_SET, primitiveSetNum); const PrimitiveSet* primitiveset = _primitives[primitiveSetNum].get(); - if (useFastPath) - { - primitiveset->draw(state, usingVertexBufferObjects); - } - else - { - 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(primitiveset); - arrayDispatchers.Begin(mode); - - unsigned int primCount=0; - unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount(); - for(unsigned int vindex=drawArray->getFirst(); - vindex(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; - - arrayDispatchers.Begin(mode); - - for(GLsizei primCount=0; - primCount<*primItr; - ++vindex,++primCount) - { - if (bindPerPrimitiveActive && (primCount%localPrimLength)==0) - { - arrayDispatchers.dispatch(BIND_PER_PRIMITIVE, primitiveNum++); - } - arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex); - } - - arrayDispatchers.End(); - - } - break; - } - case(PrimitiveSet::DrawElementsUBytePrimitiveType): - { - if (primLength==0) primLength=primitiveset->getNumIndices(); - - const DrawElementsUByte* drawElements = static_cast(primitiveset); - arrayDispatchers.Begin(mode); - - unsigned int primCount=0; - for(DrawElementsUByte::const_iterator primItr=drawElements->begin(); - primItr!=drawElements->end(); - ++primCount,++primItr) - { - - if (bindPerPrimitiveActive && (primCount%primLength)==0) - { - arrayDispatchers.dispatch(BIND_PER_PRIMITIVE, primitiveNum++); - } - - unsigned int vindex=*primItr; - arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex); - } - - arrayDispatchers.End(); - break; - } - case(PrimitiveSet::DrawElementsUShortPrimitiveType): - { - if (primLength==0) primLength=primitiveset->getNumIndices(); - - const DrawElementsUShort* drawElements = static_cast(primitiveset); - arrayDispatchers.Begin(mode); - - unsigned int primCount=0; - for(DrawElementsUShort::const_iterator primItr=drawElements->begin(); - primItr!=drawElements->end(); - ++primCount,++primItr) - { - if (bindPerPrimitiveActive && (primCount%primLength)==0) - { - arrayDispatchers.dispatch(BIND_PER_PRIMITIVE, primitiveNum++); - } - - unsigned int vindex=*primItr; - arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex); - } - - arrayDispatchers.End(); - break; - } - case(PrimitiveSet::DrawElementsUIntPrimitiveType): - { - if (primLength==0) primLength=primitiveset->getNumIndices(); - - const DrawElementsUInt* drawElements = static_cast(primitiveset); - arrayDispatchers.Begin(mode); - - unsigned int primCount=0; - for(DrawElementsUInt::const_iterator primItr=drawElements->begin(); - primItr!=drawElements->end(); - ++primCount,++primItr) - { - if (bindPerPrimitiveActive && (primCount%primLength)==0) - { - arrayDispatchers.dispatch(BIND_PER_PRIMITIVE, primitiveNum++); - } - - unsigned int vindex=*primItr; - arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex); - } - - arrayDispatchers.End(); - break; - } - default: - { - break; - } - } - } + primitiveset->draw(state, usingVertexBufferObjects); } // unbind the VBO's if any are used. @@ -1210,29 +917,29 @@ void GeometryNew::accept(AttributeFunctor& af) { AttributeFunctorArrayVisitor afav(af); - if (_vertexData.array.valid()) + if (_vertexArray.valid()) { - afav.applyArray(VERTICES,_vertexData.array.get()); + afav.applyArray(VERTICES,_vertexArray.get()); } else if (_vertexAttribList.size()>0) { OSG_INFO<<"GeometryNew::accept(AttributeFunctor& af): Using vertex attribute instead"<0) { OSG_INFO<<"GeometryNew::accept(ConstAttributeFunctor& af): Using vertex attribute instead"<0) { OSG_INFO<<"Using vertex attribute instead"<getNumElements()==0) return; @@ -1357,12 +1064,12 @@ void GeometryNew::accept(PrimitiveFunctor& functor) const void GeometryNew::accept(PrimitiveIndexFunctor& functor) const { - const osg::Array* vertices = _vertexData.array.get(); + const osg::Array* vertices = _vertexArray.get(); if (!vertices && _vertexAttribList.size()>0) { OSG_INFO<<"GeometryNew::accept(PrimitiveIndexFunctor& functor): Using vertex attribute instead"<getNumElements()==0) return; @@ -1452,48 +1159,49 @@ unsigned int _computeNumberOfPrimitives(const osg::GeometryNew& geom) } template -bool _verifyBindings(const osg::GeometryNew& geom, const A& arrayData) +bool _verifyBindings(const osg::GeometryNew& geom, const A& array) { - unsigned int numElements = arrayData.array.valid()?arrayData.array->getNumElements():0; + unsigned int numElements = array.valid()?array->getNumElements():0; - switch(arrayData.binding) + switch(array->getBinding()) { - case(osg::GeometryNew::BIND_OFF): + case(osg::Array::BIND_OFF): if (numElements>0) return false; break; - case(osg::GeometryNew::BIND_OVERALL): + case(osg::Array::BIND_OVERALL): if (numElements!=1) return false; break; - case(osg::GeometryNew::BIND_PER_PRIMITIVE_SET): + case(osg::Array::BIND_PER_PRIMITIVE_SET): if (numElements!=geom.getPrimitiveSetList().size()) return false; break; - case(osg::GeometryNew::BIND_PER_PRIMITIVE): - if (numElements!=_computeNumberOfPrimitives(geom)) return false; - break; - case(osg::GeometryNew::BIND_PER_VERTEX): + 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 -void _computeCorrectBindingsAndArraySizes(std::ostream& out, const osg::GeometryNew& geom, A& arrayData, const char* arrayName) +void _computeCorrectBindingsAndArraySizes(std::ostream& out, const osg::GeometryNew& geom, A& array, const char* arrayName) { - unsigned int numElements = arrayData.array.valid()?arrayData.array->getNumElements():0; + 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 (arrayData.binding!=osg::GeometryNew::BIND_OFF) + if (array->getBinding()!=osg::Array::BIND_OFF) { out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() "<setBinding(osg::Array::BIND_OFF); } return; } @@ -1502,11 +1210,11 @@ void _computeCorrectBindingsAndArraySizes(std::ostream& out, const osg::Geometry if (numElements==1) { // correct binding if not correct. - if (arrayData.binding!=osg::GeometryNew::BIND_OVERALL) + if (array->getBinding()!=osg::Array::BIND_OVERALL) { out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() "<setBinding(osg::Array::BIND_OVERALL); } return; } @@ -1516,10 +1224,9 @@ void _computeCorrectBindingsAndArraySizes(std::ostream& out, const osg::Geometry if ( numVertices==0 ) { - if (arrayData.binding!=osg::GeometryNew::BIND_OFF) + if (array->getBinding()!=osg::Array::BIND_OFF) { - arrayData.array = 0; - arrayData.binding = osg::GeometryNew::BIND_OFF; + array = 0; out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() vertex array is empty but "<getBinding()!=osg::Array::BIND_PER_VERTEX) { out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() "<setBinding(osg::Array::BIND_PER_VERTEX); } return; } @@ -1545,87 +1252,53 @@ void _computeCorrectBindingsAndArraySizes(std::ostream& out, const osg::Geometry if (numElements==numPrimitiveSets) { - if (arrayData.binding != osg::GeometryNew::BIND_PER_PRIMITIVE_SET) + if (array->getBinding() != osg::Array::BIND_PER_PRIMITIVE_SET) { out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() "<setBinding(osg::Array::BIND_PER_PRIMITIVE_SET); } return; } - // check to see if binding might be per primitive - unsigned int numPrimitives = _computeNumberOfPrimitives(geom); - if (numElements==numPrimitives) + if (numElements>=numVertices) { - if (arrayData.binding != osg::GeometryNew::BIND_PER_PRIMITIVE) - { - out<<"Warning: in osg::GeometryNew::computeCorrectBindingsAndArraySizes() "<setBinding(osg::Array::BIND_PER_VERTEX); return; } - - if (numElements>numVertices) + if (numElements>=numPrimitiveSets) { - arrayData.binding = osg::GeometryNew::BIND_PER_VERTEX; - return; - } - if (numElements>numPrimitives) - { - arrayData.binding = osg::GeometryNew::BIND_PER_PRIMITIVE; - return; - } - if (numElements>numPrimitiveSets) - { - arrayData.binding = osg::GeometryNew::BIND_PER_PRIMITIVE_SET; + array->setBinding(osg::Array::BIND_PER_PRIMITIVE_SET); return; } if (numElements>=1) { - arrayData.binding = osg::GeometryNew::BIND_OVERALL; + array->setBinding(osg::Array::BIND_OVERALL); return; } - arrayData.binding = osg::GeometryNew::BIND_OFF; - + array = 0; } -bool GeometryNew::verifyBindings(const ArrayData& arrayData) const +bool GeometryNew::verifyBindings(const osg::ref_ptr& array) const { - return _verifyBindings(*this,arrayData); -} - -bool GeometryNew::verifyBindings(const Vec3ArrayData& arrayData) const -{ - return _verifyBindings(*this,arrayData); -} - -void GeometryNew::computeCorrectBindingsAndArraySizes(ArrayData& arrayData, const char* arrayName) -{ - _computeCorrectBindingsAndArraySizes(osg::notify(osg::INFO),*this,arrayData,arrayName); -} - -void GeometryNew::computeCorrectBindingsAndArraySizes(Vec3ArrayData& arrayData, const char* arrayName) -{ - _computeCorrectBindingsAndArraySizes(osg::notify(osg::INFO),*this,arrayData,arrayName); + return _verifyBindings(*this, array); } bool GeometryNew::verifyBindings() const { - if (!verifyBindings(_normalData)) return false; - if (!verifyBindings(_colorData)) return false; - if (!verifyBindings(_secondaryColorData)) return false; - if (!verifyBindings(_fogCoordData)) return false; + if (!verifyBindings(_normalArray)) return false; + if (!verifyBindings(_colorArray)) return false; + if (!verifyBindings(_secondaryColorArray)) return false; + if (!verifyBindings(_fogCoordArray)) return false; - for(ArrayDataList::const_iterator titr=_texCoordList.begin(); + for(ArrayList::const_iterator titr=_texCoordList.begin(); titr!=_texCoordList.end(); ++titr) { if (!verifyBindings(*titr)) return false; } - for(ArrayDataList::const_iterator vitr=_vertexAttribList.begin(); + for(ArrayList::const_iterator vitr=_vertexAttribList.begin(); vitr!=_vertexAttribList.end(); ++vitr) { @@ -1635,23 +1308,28 @@ bool GeometryNew::verifyBindings() const return true; } +void GeometryNew::computeCorrectBindingsAndArraySizes(osg::ref_ptr& array,const char* arrayName) +{ + return _computeCorrectBindingsAndArraySizes(osg::notify(osg::INFO), *this, array, arrayName); +} + void GeometryNew::computeCorrectBindingsAndArraySizes() { // if (verifyBindings()) return; - computeCorrectBindingsAndArraySizes(_normalData,"_normalData"); - computeCorrectBindingsAndArraySizes(_colorData,"_colorData"); - computeCorrectBindingsAndArraySizes(_secondaryColorData,"_secondaryColorData"); - computeCorrectBindingsAndArraySizes(_fogCoordData,"_fogCoordData"); + computeCorrectBindingsAndArraySizes(_normalArray,"_normalArray"); + computeCorrectBindingsAndArraySizes(_colorArray,"_colorArray"); + computeCorrectBindingsAndArraySizes(_secondaryColorArray,"_secondaryColorArray"); + computeCorrectBindingsAndArraySizes(_fogCoordArray,"_fogCoordArray"); - for(ArrayDataList::iterator titr=_texCoordList.begin(); + for(ArrayList::iterator titr=_texCoordList.begin(); titr!=_texCoordList.end(); ++titr) { computeCorrectBindingsAndArraySizes(*titr,"_texCoordList[]"); } - for(ArrayDataList::iterator vitr=_vertexAttribList.begin(); + for(ArrayList::iterator vitr=_vertexAttribList.begin(); vitr!=_vertexAttribList.end(); ++vitr) { @@ -1677,8 +1355,8 @@ bool GeometryNew::containsSharedArrays() const for(unsigned int vi=0;vi<_vertexAttribList.size();++vi) { - const ArrayData& arrayData = _vertexAttribList[vi]; - if (arrayData.array.valid() && arrayData.array->referenceCount()>1) ++numSharedArrays; + const Array* array = _vertexAttribList[vi].get(); + if (array && array->referenceCount()>1) ++numSharedArrays; } return numSharedArrays!=0; } @@ -1707,10 +1385,10 @@ void GeometryNew::duplicateSharedArrays() for(unsigned int vi=0;vi<_vertexAttribList.size();++vi) { - ArrayData& arrayData = _vertexAttribList[vi]; - if (arrayData.array.valid() && arrayData.array->referenceCount()>1) + Array* array = _vertexAttribList[vi].get(); + if (array && array->referenceCount()>1) { - arrayData.array = osg::clone(arrayData.array.get(), osg::CopyOp::DEEP_COPY_ARRAYS); + _vertexAttribList[vi] = osg::clone(array, osg::CopyOp::DEEP_COPY_ARRAYS); } } } @@ -1862,20 +1540,20 @@ public: } } - bool validArray(std::ostream& out, const osg::GeometryNew::ArrayData& arrayData, const char* arrayName) + bool validArray(std::ostream& out, const osg::Array* array, const char* arrayName) { unsigned int numRequired = 0; - switch(arrayData.binding) + switch(array->getBinding()) { - case(osg::GeometryNew::BIND_OFF): numRequired = 0; break; - case(osg::GeometryNew::BIND_OVERALL): numRequired = 1; break; - case(osg::GeometryNew::BIND_PER_PRIMITIVE): numRequired = primitiveNum; break; - case(osg::GeometryNew::BIND_PER_PRIMITIVE_SET): numRequired = numPrimitiveSets; break; - case(osg::GeometryNew::BIND_PER_VERTEX): numRequired = maxVertexNumber+1; break; + 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 = arrayData.array.valid() ? arrayData.array->getNumElements() : 0; + unsigned int numElements = array ? array->getNumElements() : 0; if (numElements