diff --git a/include/osg/Drawable b/include/osg/Drawable index ba68a99d5..2360c31d1 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -469,6 +469,27 @@ class SG_EXPORT Drawable : public Object }; + class PrimitiveIndexFunctor + { + public: + + virtual ~PrimitiveIndexFunctor() {} + + virtual void setVertexArray(unsigned int count,const Vec2* vertices) = 0; + virtual void setVertexArray(unsigned int count,const Vec3* vertices) = 0; + virtual void setVertexArray(unsigned int count,const Vec4* vertices) = 0; + + virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0; + virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) = 0; + virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) = 0; + virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) = 0; + + virtual void begin(GLenum mode) = 0; + virtual void vertex(unsigned int pos) = 0; + virtual void end() = 0; + + }; + /** return true if the Drawable subclass supports accept(PrimitiveFunctor&).*/ virtual bool supports(PrimitiveFunctor&) const { return false; } @@ -478,6 +499,15 @@ class SG_EXPORT Drawable : public Object * so one cannot modify it.*/ virtual void accept(PrimitiveFunctor&) const {} + /** return true if the Drawable subclass supports accept(PrimitiveIndexFunctor&).*/ + virtual bool supports(PrimitiveIndexFunctor&) const { return false; } + + /** accept a PrimtiveIndexFunctor and call its methods to tell it about the interal primtives that this Drawable has. + * return true if functor handled by drawable, return false on failure of drawable to generate functor calls. + * Note, PrimtiveIndexFunctor only provide const access of the primtives, as primitives may be procedurally generated + * so one cannot modify it.*/ + virtual void accept(PrimitiveIndexFunctor&) const {} + /** Extensions class which encapsulates the querring of extensions and * associated function pointers, and provide convinience wrappers to diff --git a/include/osg/Geometry b/include/osg/Geometry index 0b53bc24d..a8c0a43cf 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -345,6 +345,11 @@ class SG_EXPORT Geometry : public Drawable /** accept a PrimitiveFunctor and call its methods to tell it about the interal primitives that this Drawable has.*/ virtual void accept(PrimitiveFunctor& pf) const; + /** return true, osg::Geometry does support accept(PrimitiveIndexFunctor&) .*/ + virtual bool supports(PrimitiveIndexFunctor&) const { return true; } + + /** accept a PrimitiveFunctor and call its methods to tell it about the interal primitives that this Drawable has.*/ + virtual void accept(PrimitiveIndexFunctor& pf) const; protected: diff --git a/include/osg/PrimitiveSet b/include/osg/PrimitiveSet index bc7907497..235c973ef 100644 --- a/include/osg/PrimitiveSet +++ b/include/osg/PrimitiveSet @@ -133,6 +133,7 @@ class PrimitiveSet : public Object virtual void draw() const = 0; virtual void accept(Drawable::PrimitiveFunctor& functor) const = 0; + virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const = 0; virtual unsigned int index(unsigned int pos) const = 0; virtual unsigned int getNumIndices() const = 0; @@ -206,6 +207,7 @@ class SG_EXPORT DrawArrays : public PrimitiveSet virtual void draw() const; virtual void accept(Drawable::PrimitiveFunctor& functor) const; + virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const; virtual unsigned int getNumIndices() const { return _count; } virtual unsigned int index(unsigned int pos) const { return _first+pos; } @@ -261,6 +263,7 @@ class SG_EXPORT DrawArrayLengths : public PrimitiveSet, public VectorSizei virtual void draw() const; virtual void accept(Drawable::PrimitiveFunctor& functor) const; + virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const; virtual unsigned int getNumIndices() const; virtual unsigned int index(unsigned int pos) const { return _first+pos; } @@ -319,6 +322,7 @@ class SG_EXPORT DrawElementsUByte : public PrimitiveSet, public VectorUByte virtual void draw() const ; virtual void accept(Drawable::PrimitiveFunctor& functor) const; + virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const; virtual unsigned int getNumIndices() const { return size(); } virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; } @@ -363,6 +367,7 @@ class SG_EXPORT DrawElementsUShort : public PrimitiveSet, public VectorUShort virtual void draw() const; virtual void accept(Drawable::PrimitiveFunctor& functor) const; + virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const; virtual unsigned int getNumIndices() const { return size(); } virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; } @@ -406,6 +411,7 @@ class SG_EXPORT DrawElementsUInt : public PrimitiveSet, public VectorUInt virtual void draw() const; virtual void accept(Drawable::PrimitiveFunctor& functor) const; + virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const; virtual unsigned int getNumIndices() const { return size(); } virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; } diff --git a/include/osg/TriangleIndexFunctor b/include/osg/TriangleIndexFunctor index 96e3f44cc..4cbf4c5d6 100644 --- a/include/osg/TriangleIndexFunctor +++ b/include/osg/TriangleIndexFunctor @@ -20,58 +20,40 @@ namespace osg { template -class TriangleIndexFunctor : public Drawable::PrimitiveFunctor, public T +class TriangleIndexFunctor : public Drawable::PrimitiveIndexFunctor, public T { public: virtual void setVertexArray(unsigned int,const Vec2*) { - notify(WARN)<<"TriangleIndexFunctor does not support Vec2* vertex arrays"< _indexCache; }; } diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index 8097635e5..63b8fbcbd 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -1976,6 +1976,142 @@ void Geometry::accept(PrimitiveFunctor& functor) const return; } +void Geometry::accept(PrimitiveIndexFunctor& functor) const +{ + if (!_vertexData.array.valid() || _vertexData.array->getNumElements()==0) return; + + switch(_vertexData.array->getType()) + { + case(Array::Vec2ArrayType): + functor.setVertexArray(_vertexData.array->getNumElements(),static_cast(_vertexData.array->getDataPointer())); + break; + case(Array::Vec3ArrayType): + functor.setVertexArray(_vertexData.array->getNumElements(),static_cast(_vertexData.array->getDataPointer())); + break; + case(Array::Vec4ArrayType): + functor.setVertexArray(_vertexData.array->getNumElements(),static_cast(_vertexData.array->getDataPointer())); + break; + default: + notify(WARN)<<"Warning: Geometry::accept(PrimtiveIndexFunctor&) cannot handle Vertex Array type"<<_vertexData.array->getType()<accept(functor); + } + } + else + { + for(PrimitiveSetList::const_iterator itr=_primitives.begin(); + itr!=_primitives.end(); + ++itr) + { + const PrimitiveSet* primitiveset = itr->get(); + GLenum mode=primitiveset->getMode(); + switch(primitiveset->getType()) + { + case(PrimitiveSet::DrawArraysPrimitiveType): + { + const DrawArrays* drawArray = static_cast(primitiveset); + functor.begin(mode); + + unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount(); + for(unsigned int vindex=drawArray->getFirst(); + vindexindex(vindex)); + } + + functor.end(); + break; + } + case(PrimitiveSet::DrawArrayLengthsPrimitiveType): + { + + const DrawArrayLengths* drawArrayLengths = static_cast(primitiveset); + unsigned int vindex=drawArrayLengths->getFirst(); + for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin(); + primItr!=drawArrayLengths->end(); + ++primItr) + { + + functor.begin(mode); + + for(GLsizei primCount=0;primCount<*primItr;++primCount) + { + functor.vertex(_vertexData.indices->index(vindex)); + ++vindex; + } + + functor.end(); + + } + break; + } + case(PrimitiveSet::DrawElementsUBytePrimitiveType): + { + const DrawElementsUByte* drawElements = static_cast(primitiveset); + functor.begin(mode); + + unsigned int primCount=0; + for(DrawElementsUByte::const_iterator primItr=drawElements->begin(); + primItr!=drawElements->end(); + ++primCount,++primItr) + { + unsigned int vindex=*primItr; + functor.vertex(_vertexData.indices->index(vindex)); + } + + functor.end(); + break; + } + case(PrimitiveSet::DrawElementsUShortPrimitiveType): + { + const DrawElementsUShort* drawElements = static_cast(primitiveset); + functor.begin(mode); + + for(DrawElementsUShort::const_iterator primItr=drawElements->begin(); + primItr!=drawElements->end(); + ++primItr) + { + unsigned int vindex=*primItr; + functor.vertex(_vertexData.indices->index(vindex)); + } + + functor.end(); + break; + } + case(PrimitiveSet::DrawElementsUIntPrimitiveType): + { + const DrawElementsUInt* drawElements = static_cast(primitiveset); + functor.begin(mode); + + for(DrawElementsUInt::const_iterator primItr=drawElements->begin(); + primItr!=drawElements->end(); + ++primItr) + { + unsigned int vindex=*primItr; + functor.vertex(_vertexData.indices->index(vindex)); + } + + functor.end(); + break; + } + default: + { + break; + } + } + } + } + return; +} unsigned int _computeNumberOfPrimtives(const osg::Geometry& geom) { diff --git a/src/osg/PrimitiveSet.cpp b/src/osg/PrimitiveSet.cpp index fd70ff0dc..251e902c1 100644 --- a/src/osg/PrimitiveSet.cpp +++ b/src/osg/PrimitiveSet.cpp @@ -24,6 +24,11 @@ void DrawArrays::accept(Drawable::PrimitiveFunctor& functor) const functor.drawArrays(_mode,_first,_count); } +void DrawArrays::accept(Drawable::PrimitiveIndexFunctor& functor) const +{ + functor.drawArrays(_mode,_first,_count); +} + void DrawArrayLengths::draw() const { GLint first = _first; @@ -48,6 +53,18 @@ void DrawArrayLengths::accept(Drawable::PrimitiveFunctor& functor) const } } +void DrawArrayLengths::accept(Drawable::PrimitiveIndexFunctor& functor) const +{ + GLint first = _first; + for(VectorSizei::const_iterator itr=begin(); + itr!=end(); + ++itr) + { + functor.drawArrays(_mode,first,*itr); + first += *itr; + } +} + unsigned int DrawArrayLengths::getNumIndices() const { unsigned int count = 0; @@ -70,6 +87,11 @@ void DrawElementsUByte::accept(Drawable::PrimitiveFunctor& functor) const if (!empty()) functor.drawElements(_mode,size(),&front()); } +void DrawElementsUByte::accept(Drawable::PrimitiveIndexFunctor& functor) const +{ + if (!empty()) functor.drawElements(_mode,size(),&front()); +} + void DrawElementsUByte::offsetIndices(int offset) { for(iterator itr=begin(); @@ -91,6 +113,11 @@ void DrawElementsUShort::accept(Drawable::PrimitiveFunctor& functor) const if (!empty()) functor.drawElements(_mode,size(),&front()); } +void DrawElementsUShort::accept(Drawable::PrimitiveIndexFunctor& functor) const +{ + if (!empty()) functor.drawElements(_mode,size(),&front()); +} + void DrawElementsUShort::offsetIndices(int offset) { for(iterator itr=begin(); @@ -112,6 +139,11 @@ void DrawElementsUInt::accept(Drawable::PrimitiveFunctor& functor) const if (!empty()) functor.drawElements(_mode,size(),&front()); } +void DrawElementsUInt::accept(Drawable::PrimitiveIndexFunctor& functor) const +{ + if (!empty()) functor.drawElements(_mode,size(),&front()); +} + void DrawElementsUInt::offsetIndices(int offset) { for(iterator itr=begin();