/* -*-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 #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 BufferData { public: enum Type { ArrayType = 0, ByteArrayType = 1, ShortArrayType = 2, IntArrayType = 3, UByteArrayType = 4, UShortArrayType = 5, UIntArrayType = 6, FloatArrayType = 7, DoubleArrayType = 8, Vec2bArrayType = 9, Vec3bArrayType = 10, Vec4bArrayType = 11, Vec2sArrayType = 12, Vec3sArrayType = 13, Vec4sArrayType = 14, Vec2iArrayType = 15, Vec3iArrayType = 16, Vec4iArrayType = 17, Vec2ubArrayType = 18, Vec3ubArrayType = 19, Vec4ubArrayType = 20, Vec2usArrayType = 21, Vec3usArrayType = 22, Vec4usArrayType = 23, Vec2uiArrayType = 24, Vec3uiArrayType = 25, Vec4uiArrayType = 26, Vec2ArrayType = 27, Vec3ArrayType = 28, Vec4ArrayType = 29, Vec2dArrayType = 30, Vec3dArrayType = 31, Vec4dArrayType = 32, MatrixArrayType = 33, MatrixdArrayType = 34 }; enum Binding { BIND_UNDEFINED=-1, BIND_OFF=0, BIND_OVERALL=1, BIND_PER_PRIMITIVE_SET=2, BIND_PER_VERTEX=4 }; Array(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0, Binding binding=BIND_UNDEFINED): _arrayType(arrayType), _dataSize(dataSize), _dataType(dataType), _binding(binding), _normalize(false), _preserveDataType(false) {} Array(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): BufferData(array,copyop), _arrayType(array._arrayType), _dataSize(array._dataSize), _dataType(array._dataType), _binding(array._binding), _normalize(array._normalize), _preserveDataType(array._preserveDataType) {} 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 osg::Array* asArray() { return this; } virtual const osg::Array* asArray() const { return this; } virtual unsigned int getElementSize() const = 0; virtual const GLvoid* getDataPointer() const = 0; virtual unsigned int getTotalDataSize() const = 0; virtual unsigned int getNumElements() const = 0; virtual void reserveArray(unsigned int num) = 0; virtual void resizeArray(unsigned int num) = 0; /** 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; } /** Specify whether the array data should be normalized by OpenGL.*/ void setNormalize(bool normalize) { _normalize = normalize; } /** Get whether the array data should be normalized by OpenGL.*/ bool getNormalize() const { return _normalize; } /** Set hint to ask that the array data is passed via integer or double, or normal setVertexAttribPointer function.*/ void setPreserveDataType(bool preserve) { _preserveDataType = preserve; } /** Get hint to ask that the array data is passed via integer or double, or normal setVertexAttribPointer function.*/ bool getPreserveDataType() const { return _preserveDataType; } /** Frees unused space on this vector - i.e. the difference between size() and max_size() of the underlying vector.*/ virtual void trim() {} /** Set the VertexBufferObject.*/ inline void setVertexBufferObject(osg::VertexBufferObject* vbo) { setBufferObject(vbo); } /** Get the VertexBufferObject. If no VBO is assigned returns NULL*/ inline osg::VertexBufferObject* getVertexBufferObject() { return dynamic_cast(_bufferObject.get()); } /** Get the const VertexBufferObject. If no VBO is assigned returns NULL*/ inline const osg::VertexBufferObject* getVertexBufferObject() const { return dynamic_cast(_bufferObject.get()); } protected: virtual ~Array() {} Type _arrayType; GLint _dataSize; GLenum _dataType; Binding _binding; bool _normalize; bool _preserveDataType; }; /** convinience function for getting the binding of array via a ptr that may be null.*/ inline osg::Array::Binding getBinding(const osg::Array* array) { return array ? array->getBinding() : osg::Array::BIND_OFF; } /** convinience function for getting the binding of array via a ptr that may be null.*/ inline bool getNormalize(const osg::Array* array) { return array ? array->getNormalize() : false; } template class TemplateArray : public Array, public MixinVector { public: TemplateArray(Binding binding=BIND_UNDEFINED) : Array(ARRAYTYPE,DataSize,DataType, binding) {} TemplateArray(const TemplateArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Array(ta,copyop), MixinVector(ta) {} TemplateArray(unsigned int no) : Array(ARRAYTYPE,DataSize,DataType), MixinVector(no) {} TemplateArray(unsigned int no,const T* ptr) : Array(ARRAYTYPE,DataSize,DataType), MixinVector(ptr,ptr+no) {} TemplateArray(Binding binding, unsigned int no) : Array(ARRAYTYPE,DataSize,DataType, binding), MixinVector(no) {} TemplateArray(Binding binding, unsigned int no,const T* ptr) : Array(ARRAYTYPE,DataSize,DataType, binding), MixinVector(ptr,ptr+no) {} template TemplateArray(InputIterator first,InputIterator last) : Array(ARRAYTYPE,DataSize,DataType), MixinVector(first,last) {} TemplateArray& operator = (const TemplateArray& array) { if (this==&array) return *this; 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 unsigned int getElementSize() const { return sizeof(ElementDataType); } virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; } virtual unsigned int getTotalDataSize() const { return static_cast(this->size()*sizeof(ElementDataType)); } virtual unsigned int getNumElements() const { return static_cast(this->size()); } virtual void reserveArray(unsigned int num) { this->reserve(num); } virtual void resizeArray(unsigned int num) { this->resize(num); } 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 MixinVector { public: TemplateIndexArray() : IndexArray(ARRAYTYPE,DataSize,DataType) {} TemplateIndexArray(const TemplateIndexArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY): IndexArray(ta,copyop), MixinVector(ta) {} TemplateIndexArray(unsigned int no) : IndexArray(ARRAYTYPE,DataSize,DataType), MixinVector(no) {} TemplateIndexArray(unsigned int no,T* ptr) : IndexArray(ARRAYTYPE,DataSize,DataType), MixinVector(ptr,ptr+no) {} template TemplateIndexArray(InputIterator first,InputIterator last) : IndexArray(ARRAYTYPE,DataSize,DataType), MixinVector(first,last) {} TemplateIndexArray& operator = (const TemplateIndexArray& array) { if (this==&array) return *this; 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 unsigned int getElementSize() const { return sizeof(ElementDataType); } virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; } virtual unsigned int getTotalDataSize() const { return static_cast(this->size()*sizeof(T)); } virtual unsigned int getNumElements() const { return static_cast(this->size()); } virtual void reserveArray(unsigned int num) { this->reserve(num); } virtual void resizeArray(unsigned int num) { this->resize(num); } 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 DoubleArray; typedef TemplateArray Vec2bArray; typedef TemplateArray Vec3bArray; typedef TemplateArray Vec4bArray; typedef TemplateArray Vec2sArray; typedef TemplateArray Vec3sArray; typedef TemplateArray Vec4sArray; typedef TemplateArray Vec2iArray; typedef TemplateArray Vec3iArray; typedef TemplateArray Vec4iArray; typedef TemplateArray Vec2ubArray; typedef TemplateArray Vec3ubArray; typedef TemplateArray Vec4ubArray; typedef TemplateArray Vec2usArray; typedef TemplateArray Vec3usArray; typedef TemplateArray Vec4usArray; typedef TemplateArray Vec2uiArray; typedef TemplateArray Vec3uiArray; typedef TemplateArray Vec4uiArray; typedef TemplateArray Vec2Array; typedef TemplateArray Vec3Array; typedef TemplateArray Vec4Array; typedef TemplateArray Vec2dArray; typedef TemplateArray Vec3dArray; typedef TemplateArray Vec4dArray; typedef TemplateArray MatrixfArray; typedef TemplateArray MatrixdArray; 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(Vec2bArray&) {} virtual void apply(Vec3bArray&) {} virtual void apply(Vec4bArray&) {} virtual void apply(Vec2sArray&) {} virtual void apply(Vec3sArray&) {} virtual void apply(Vec4sArray&) {} virtual void apply(Vec2iArray&) {} virtual void apply(Vec3iArray&) {} virtual void apply(Vec4iArray&) {} virtual void apply(Vec2ubArray&) {} virtual void apply(Vec3ubArray&) {} virtual void apply(Vec4ubArray&) {} virtual void apply(Vec2usArray&) {} virtual void apply(Vec3usArray&) {} virtual void apply(Vec4usArray&) {} virtual void apply(Vec2uiArray&) {} virtual void apply(Vec3uiArray&) {} virtual void apply(Vec4uiArray&) {} virtual void apply(Vec2Array&) {} virtual void apply(Vec3Array&) {} virtual void apply(Vec4Array&) {} virtual void apply(Vec2dArray&) {} virtual void apply(Vec3dArray&) {} virtual void apply(Vec4dArray&) {} virtual void apply(MatrixfArray&) {} virtual void apply(MatrixdArray&) {} }; 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 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 Vec2iArray&) {} virtual void apply(const Vec3iArray&) {} virtual void apply(const Vec4iArray&) {} virtual void apply(const Vec2ubArray&) {} virtual void apply(const Vec3ubArray&) {} virtual void apply(const Vec4ubArray&) {} virtual void apply(const Vec2usArray&) {} virtual void apply(const Vec3usArray&) {} virtual void apply(const Vec4usArray&) {} virtual void apply(const Vec2uiArray&) {} virtual void apply(const Vec3uiArray&) {} virtual void apply(const Vec4uiArray&) {} virtual void apply(const Vec2Array&) {} virtual void apply(const Vec3Array&) {} virtual void apply(const Vec4Array&) {} virtual void apply(const Vec2dArray&) {} virtual void apply(const Vec3dArray&) {} virtual void apply(const Vec4dArray&) {} virtual void apply(const MatrixfArray&) {} virtual void apply(const MatrixdArray&) {} }; 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(Vec2b&) {} virtual void apply(Vec3b&) {} virtual void apply(Vec4b&) {} virtual void apply(Vec2s&) {} virtual void apply(Vec3s&) {} virtual void apply(Vec4s&) {} virtual void apply(Vec2i&) {} virtual void apply(Vec3i&) {} virtual void apply(Vec4i&) {} virtual void apply(Vec2ub&) {} virtual void apply(Vec3ub&) {} virtual void apply(Vec4ub&) {} virtual void apply(Vec2us&) {} virtual void apply(Vec3us&) {} virtual void apply(Vec4us&) {} virtual void apply(Vec2ui&) {} virtual void apply(Vec3ui&) {} virtual void apply(Vec4ui&) {} virtual void apply(Vec2&) {} virtual void apply(Vec3&) {} virtual void apply(Vec4&) {} virtual void apply(Vec2d&) {} virtual void apply(Vec3d&) {} virtual void apply(Vec4d&) {} virtual void apply(Matrixf&) {} virtual void apply(Matrixd&) {} }; 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 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 Vec2i&) {} virtual void apply(const Vec3i&) {} virtual void apply(const Vec4i&) {} virtual void apply(const Vec2ub&) {} virtual void apply(const Vec3ub&) {} virtual void apply(const Vec4ub&) {} virtual void apply(const Vec2us&) {} virtual void apply(const Vec3us&) {} virtual void apply(const Vec4us&) {} virtual void apply(const Vec2ui&) {} virtual void apply(const Vec3ui&) {} virtual void apply(const Vec4ui&) {} virtual void apply(const Vec2&) {} virtual void apply(const Vec3&) {} virtual void apply(const Vec4&) {} virtual void apply(const Vec2d&) {} virtual void apply(const Vec3d&) {} virtual void apply(const Vec4d&) {} virtual void apply(const Matrixf&) {} virtual void apply(const Matrixd&) {} }; 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