/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #ifndef OSG_ARRAY #define OSG_ARRAY 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace osg { class ArrayVisitor; class ConstArrayVisitor; class ValueVisitor; class ConstValueVisitor; class OSG_EXPORT Array : public Object { public: enum Type { ArrayType = 0, ByteArrayType = 1, ShortArrayType = 2, IntArrayType = 3, UByteArrayType = 4, UShortArrayType = 5, UIntArrayType = 6, Vec4ubArrayType = 7, FloatArrayType = 8, Vec2ArrayType = 9, Vec3ArrayType = 10, Vec4ArrayType = 11, Vec2sArrayType = 12, Vec3sArrayType = 13, Vec4sArrayType = 14, Vec2bArrayType = 15, Vec3bArrayType = 16, Vec4bArrayType = 17, DoubleArrayType = 18, Vec2dArrayType = 19, Vec3dArrayType = 20, Vec4dArrayType = 21 }; Array(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0): _arrayType(arrayType), _dataSize(dataSize), _dataType(dataType), _modifiedCount(0), _vboOffset(0) {} Array(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Object(array,copyop), _arrayType(array._arrayType), _dataSize(array._dataSize), _dataType(array._dataType), _modifiedCount(0), _vboOffset(0) {} virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } virtual const char* libraryName() const { return "osg"; } virtual const char* className() const; virtual void accept(ArrayVisitor&) = 0; virtual void accept(ConstArrayVisitor&) const = 0; virtual void accept(unsigned int index,ValueVisitor&) = 0; virtual void accept(unsigned int index,ConstValueVisitor&) const = 0; /** Return -1 if lhs element is less than rhs element, 0 if equal, * 1 if lhs element is greater than rhs element. */ virtual int compare(unsigned int lhs,unsigned int rhs) const = 0; Type getType() const { return _arrayType; } GLint getDataSize() const { return _dataSize; } GLenum getDataType() const { return _dataType; } virtual const GLvoid* getDataPointer() const = 0; virtual unsigned int getTotalDataSize() const = 0; virtual unsigned int getNumElements() const = 0; /** Frees unused space on this vector - i.e. the difference between size() and max_size() of the underlying vector.*/ virtual void trim() {} /** Dirty the primitive, which increments the modified count, to force buffer objects to update. */ inline void dirty() { ++_modifiedCount; if (_vbo.valid()) _vbo->dirty(); } /** Set the modified count value.*/ inline void setModifiedCount(unsigned int value) { _modifiedCount=value; } /** Get modified count value.*/ inline unsigned int getModifiedCount() const { return _modifiedCount; } /** Set the VertexBufferObject.*/ inline void setVertexBufferObject(osg::VertexBufferObject* vbo) { if (_vbo == vbo) return; if (_vbo.valid()) { _vbo->removeArray(this); } _vbo = vbo; if (_vbo.valid()) { _vbo->addArray(this); } } /** Get the VertexBufferObject. If no VBO is assigned returns NULL*/ inline osg::VertexBufferObject* getVertexBufferObject() { return _vbo.get(); } /** Get the const VertexBufferObject. If no VBO is assigned returns NULL*/ inline const osg::VertexBufferObject* getVertexBufferObject() const { return _vbo.get(); } /** Set the offset into the VertexBufferObject, if used.*/ void setVertexBufferObjectOffset(const GLvoid* offset ) const { _vboOffset = offset; } /** Get the offset into the VertexBufferObject, if used.*/ const GLvoid* getVertexBufferObjectOffset() const { return _vboOffset; } protected: virtual ~Array() { if (_vbo.valid()) { _vbo->removeArray(this); } } Type _arrayType; GLint _dataSize; GLenum _dataType; unsigned int _modifiedCount; osg::ref_ptr _vbo; mutable const GLvoid* _vboOffset; }; template class TemplateArray : public Array, public std::vector { public: TemplateArray() : Array(ARRAYTYPE,DataSize,DataType) {} TemplateArray(const TemplateArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Array(ta,copyop), std::vector(ta) {} TemplateArray(unsigned int no) : Array(ARRAYTYPE,DataSize,DataType), std::vector(no) {} TemplateArray(unsigned int no,T* ptr) : Array(ARRAYTYPE,DataSize,DataType), std::vector(ptr,ptr+no) {} template TemplateArray(InputIterator first,InputIterator last) : Array(ARRAYTYPE,DataSize,DataType), std::vector(first,last) {} TemplateArray& operator = (const TemplateArray& array) { if (this==&array) return *this; assign(array.begin(),array.end()); return *this; } virtual Object* cloneType() const { return new TemplateArray(); } virtual Object* clone(const CopyOp& copyop) const { return new TemplateArray(*this,copyop); } inline virtual void accept(ArrayVisitor& av); inline virtual void accept(ConstArrayVisitor& av) const; inline virtual void accept(unsigned int index,ValueVisitor& vv); inline virtual void accept(unsigned int index,ConstValueVisitor& vv) const; virtual int compare(unsigned int lhs,unsigned int rhs) const { const T& elem_lhs = (*this)[lhs]; const T& elem_rhs = (*this)[rhs]; if (elem_lhs( *this ).swap( *this ); } virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; } virtual unsigned int getTotalDataSize() const { return this->size()*sizeof(T); } virtual unsigned int getNumElements() const { return this->size(); } typedef T ElementDataType; // expose T protected: virtual ~TemplateArray() {} }; class OSG_EXPORT IndexArray : public Array { public: IndexArray(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0): Array(arrayType,dataSize,dataType) {} IndexArray(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Array(array,copyop) {} virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } virtual unsigned int index(unsigned int pos) const = 0; protected: virtual ~IndexArray() {} }; template class TemplateIndexArray : public IndexArray, public std::vector { public: TemplateIndexArray() : IndexArray(ARRAYTYPE,DataSize,DataType) {} TemplateIndexArray(const TemplateIndexArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY): IndexArray(ta,copyop), std::vector(ta) {} TemplateIndexArray(unsigned int no) : IndexArray(ARRAYTYPE,DataSize,DataType), std::vector(no) {} TemplateIndexArray(unsigned int no,T* ptr) : IndexArray(ARRAYTYPE,DataSize,DataType), std::vector(ptr,ptr+no) {} template TemplateIndexArray(InputIterator first,InputIterator last) : IndexArray(ARRAYTYPE,DataSize,DataType), std::vector(first,last) {} TemplateIndexArray& operator = (const TemplateIndexArray& array) { if (this==&array) return *this; assign(array.begin(),array.end()); return *this; } virtual Object* cloneType() const { return new TemplateIndexArray(); } virtual Object* clone(const CopyOp& copyop) const { return new TemplateIndexArray(*this,copyop); } inline virtual void accept(ArrayVisitor& av); inline virtual void accept(ConstArrayVisitor& av) const; inline virtual void accept(unsigned int index,ValueVisitor& vv); inline virtual void accept(unsigned int index,ConstValueVisitor& vv) const; virtual int compare(unsigned int lhs,unsigned int rhs) const { const T& elem_lhs = (*this)[lhs]; const T& elem_rhs = (*this)[rhs]; if (elem_lhs( *this ).swap( *this ); } virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; } virtual unsigned int getTotalDataSize() const { return this->size()*sizeof(T); } virtual unsigned int getNumElements() const { return this->size(); } virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; } typedef T ElementDataType; // expose T protected: virtual ~TemplateIndexArray() {} }; typedef TemplateIndexArray ByteArray; typedef TemplateIndexArray ShortArray; typedef TemplateIndexArray IntArray; typedef TemplateIndexArray UByteArray; typedef TemplateIndexArray UShortArray; typedef TemplateIndexArray UIntArray; typedef TemplateArray FloatArray; typedef TemplateArray Vec2Array; typedef TemplateArray Vec3Array; typedef TemplateArray Vec4Array; typedef TemplateArray Vec4ubArray; typedef TemplateArray Vec2sArray; typedef TemplateArray Vec3sArray; typedef TemplateArray Vec4sArray; typedef TemplateArray Vec2bArray; typedef TemplateArray Vec3bArray; typedef TemplateArray Vec4bArray; typedef TemplateArray DoubleArray; typedef TemplateArray Vec2dArray; typedef TemplateArray Vec3dArray; typedef TemplateArray Vec4dArray; class ArrayVisitor { public: ArrayVisitor() {} virtual ~ArrayVisitor() {} virtual void apply(Array&) {} virtual void apply(ByteArray&) {} virtual void apply(ShortArray&) {} virtual void apply(IntArray&) {} virtual void apply(UByteArray&) {} virtual void apply(UShortArray&) {} virtual void apply(UIntArray&) {} virtual void apply(FloatArray&) {} virtual void apply(DoubleArray&) {} virtual void apply(Vec2Array&) {} virtual void apply(Vec3Array&) {} virtual void apply(Vec4Array&) {} virtual void apply(Vec4ubArray&) {} virtual void apply(Vec2bArray&) {} virtual void apply(Vec3bArray&) {} virtual void apply(Vec4bArray&) {} virtual void apply(Vec2sArray&) {} virtual void apply(Vec3sArray&) {} virtual void apply(Vec4sArray&) {} virtual void apply(Vec2dArray&) {} virtual void apply(Vec3dArray&) {} virtual void apply(Vec4dArray&) {} }; class ConstArrayVisitor { public: ConstArrayVisitor() {} virtual ~ConstArrayVisitor() {} virtual void apply(const Array&) {} virtual void apply(const ByteArray&) {} virtual void apply(const ShortArray&) {} virtual void apply(const IntArray&) {} virtual void apply(const UByteArray&) {} virtual void apply(const UShortArray&) {} virtual void apply(const UIntArray&) {} virtual void apply(const FloatArray&) {} virtual void apply(const DoubleArray&) {} virtual void apply(const Vec2Array&) {} virtual void apply(const Vec3Array&) {} virtual void apply(const Vec4Array&) {} virtual void apply(const Vec4ubArray&) {} virtual void apply(const Vec2bArray&) {} virtual void apply(const Vec3bArray&) {} virtual void apply(const Vec4bArray&) {} virtual void apply(const Vec2sArray&) {} virtual void apply(const Vec3sArray&) {} virtual void apply(const Vec4sArray&) {} virtual void apply(const Vec2dArray&) {} virtual void apply(const Vec3dArray&) {} virtual void apply(const Vec4dArray&) {} }; class ValueVisitor { public: ValueVisitor() {} virtual ~ValueVisitor() {} virtual void apply(GLbyte&) {} virtual void apply(GLshort&) {} virtual void apply(GLint&) {} virtual void apply(GLushort&) {} virtual void apply(GLubyte&) {} virtual void apply(GLuint&) {} virtual void apply(GLfloat&) {} virtual void apply(GLdouble&) {} virtual void apply(Vec2&) {} virtual void apply(Vec3&) {} virtual void apply(Vec4&) {} virtual void apply(Vec4ub&) {} virtual void apply(Vec2b&) {} virtual void apply(Vec3b&) {} virtual void apply(Vec4b&) {} virtual void apply(Vec2s&) {} virtual void apply(Vec3s&) {} virtual void apply(Vec4s&) {} virtual void apply(Vec2d&) {} virtual void apply(Vec3d&) {} virtual void apply(Vec4d&) {} }; class ConstValueVisitor { public: ConstValueVisitor() {} virtual ~ConstValueVisitor() {} virtual void apply(const GLbyte&) {} virtual void apply(const GLshort&) {} virtual void apply(const GLint&) {} virtual void apply(const GLushort&) {} virtual void apply(const GLubyte&) {} virtual void apply(const GLuint&) {} virtual void apply(const GLfloat&) {} virtual void apply(const GLdouble&) {} virtual void apply(const Vec4ub&) {} virtual void apply(const Vec2&) {} virtual void apply(const Vec3&) {} virtual void apply(const Vec4&) {} virtual void apply(const Vec2b&) {} virtual void apply(const Vec3b&) {} virtual void apply(const Vec4b&) {} virtual void apply(const Vec2s&) {} virtual void apply(const Vec3s&) {} virtual void apply(const Vec4s&) {} virtual void apply(const Vec2d&) {} virtual void apply(const Vec3d&) {} virtual void apply(const Vec4d&) {} }; template inline void TemplateArray::accept(ArrayVisitor& av) { av.apply(*this); } template inline void TemplateArray::accept(ConstArrayVisitor& av) const { av.apply(*this); } template inline void TemplateArray::accept(unsigned int index,ValueVisitor& vv) { vv.apply( (*this)[index] ); } template inline void TemplateArray::accept(unsigned int index,ConstValueVisitor& vv) const { vv.apply( (*this)[index] );} template inline void TemplateIndexArray::accept(ArrayVisitor& av) { av.apply(*this); } template inline void TemplateIndexArray::accept(ConstArrayVisitor& av) const { av.apply(*this); } template inline void TemplateIndexArray::accept(unsigned int index,ValueVisitor& vv) { vv.apply( (*this)[index] ); } template inline void TemplateIndexArray::accept(unsigned int index,ConstValueVisitor& vv) const { vv.apply( (*this)[index] );} } #endif