/**************************************************************************************/ /* */ /* Visualization Library */ /* http://visualizationlibrary.org */ /* */ /* Copyright (c) 2005-2020, Michele Bosi */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or without modification, */ /* are permitted provided that the following conditions are met: */ /* */ /* - Redistributions of source code must retain the above copyright notice, this */ /* list of conditions and the following disclaimer. */ /* */ /* - Redistributions in binary form must reproduce the above copyright notice, this */ /* list of conditions and the following disclaimer in the documentation and/or */ /* other materials provided with the distribution. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /**************************************************************************************/ #ifndef Array_INCLUDE_ONCE #define Array_INCLUDE_ONCE #include #include #include namespace vl { //----------------------------------------------------------------------------- // ArrayAbstract //----------------------------------------------------------------------------- /** * The ArrayAbstract class defines an abstract interface to conveniently manipulate data stored in a BufferObject. * \sa * * - vl::Array * - vl::ArrayFloat1, vl::ArrayFloat2, vl::ArrayFloat3, vl::ArrayFloat4 * - vl::ArrayDouble1, vl::ArrayDouble2, vl::ArrayDouble3, vl::ArrayDouble4 * - vl::ArrayInt1, vl::ArrayInt2, vl::ArrayInt3, vl::ArrayInt4 * - vl::ArrayUInt1, vl::ArrayUInt2, vl::ArrayUInt3, vl::ArrayUInt4 * - vl::ArrayByte1, vl::ArrayByte2, vl::ArrayByte3, vl::ArrayByte4 * - vl::ArrayUByte1, vl::ArrayUByte2, vl::ArrayUByte3, vl::ArrayUByte4 * - vl::ArrayShort1, vl::ArrayShort2, vl::ArrayShort3, vl::ArrayShort4 * - vl::ArrayUShort1, vl::ArrayUShort2, vl::ArrayUShort3, vl::ArrayUShort4 */ class ArrayAbstract: public Object { VL_INSTRUMENT_ABSTRACT_CLASS(vl::ArrayAbstract, Object) public: //! Default constructor. ArrayAbstract() { VL_DEBUG_SET_OBJECT_NAME() mBufferObject = new BufferObject; mBufferObjectDirty = true; mBufferObjectUsage = vl::BU_STATIC_DRAW; mInterpretation = VAI_NORMAL; mNormalize = false; } //! Copies only the local data and not the BufferObject related fields ArrayAbstract(const ArrayAbstract& other): Object(other) { VL_DEBUG_SET_OBJECT_NAME() mBufferObject = new BufferObject; mBufferObjectDirty = true; mBufferObjectUsage = vl::BU_STATIC_DRAW; mInterpretation = VAI_NORMAL; mNormalize = false; operator=(other); } //! Copies only the local data and not the BufferObject related fields void operator=(const ArrayAbstract& other) { bufferObject()->resize( other.bufferObject()->bytesUsed() ); memcpy( ptr(), other.ptr(), bytesUsed() ); mInterpretation = other.mInterpretation; mNormalize = other.mNormalize; } virtual ref clone() const = 0; const BufferObject* bufferObject() const { return mBufferObject.get(); } BufferObject* bufferObject() { return mBufferObject.get(); } void clear() { if (bufferObject()) bufferObject()->clear(); } //! Returns the pointer to the first element of the local buffer. Equivalent to bufferObject()->ptr() const unsigned char* ptr() const { return bufferObject() ? bufferObject()->ptr() : NULL; } //! Returns the pointer to the first element of the local buffer. Equivalent to bufferObject()->ptr() unsigned char* ptr() { return bufferObject() ? bufferObject()->ptr() : NULL; } //! Returns the amount of memory in bytes used by an array. Equivalent to bufferObject()->bytesUsed(). virtual size_t bytesUsed() const { return bufferObject() ? bufferObject()->bytesUsed() : 0; } //! Returns the number of scalar components for the array, ie 3 for ArrayFloat3, 1 for ArrayUInt1 etc. virtual size_t glSize() const = 0; //! Returns the OpenGL type for the array, ie GL_FLOAT for ArrayFloat3, GL_UNSIGNED_INT for ArrayUInt1 etc. virtual GLenum glType() const = 0; //! Returns the number of elements of an array virtual size_t size() const = 0; //! Computes the bounding sphere enclosing the vectors contained in the buffer. virtual Sphere computeBoundingSphere() const = 0; //! Computes the axis aligned bounding box enclosing the vectors contained in the buffer. virtual AABB computeBoundingBox() const = 0; //! Transforms the vectors contained in the buffer virtual void transform(const mat4& m) = 0; //! Normalizes the vectors contained in the buffer virtual void normalize() = 0; //! Returns a vector from the buffer as a \p vec4 value. virtual vec4 getAsVec4(size_t vector_index) const = 0; //! Returns a vector from the buffer as a \p vec3 value. virtual vec3 getAsVec3(size_t vector_index) const = 0; //! Returns a vector from the buffer as a \p vec2 value. virtual vec2 getAsVec2(size_t vector_index) const = 0; //! Compares two vectors virtual int compare(int a, int b) const = 0; //! Wether the BufferObject should be updated or not using the local storage. Initially set to true. //! IMPORTANT: To automatically update the buffer object of a Renderable, Geometry etc. you also need to call Renderable::setBufferObjectDirty(). //! IMPORTANT: To immediately update the buffer object manually call the updateBufferObject() method of this class. bool isBufferObjectDirty() const { return mBufferObjectDirty; } //! Wether the BufferObject should be updated or not using the local storage. Initially set to true. //! IMPORTANT: To automatically update the buffer object of a Renderable, Geometry etc. you also need to call Renderable::setBufferObjectDirty(). //! IMPORTANT: To immediately update the buffer object manually call the updateBufferObject() method of this class. void setBufferObjectDirty(bool dirty=true) { mBufferObjectDirty = dirty; } //! BU_STATIC_DRAW by default EBufferObjectUsage usage() const { return mBufferObjectUsage; } //! BU_STATIC_DRAW by default void setUsage(EBufferObjectUsage usage) { mBufferObjectUsage = usage; } //! Updates the BufferObject. //! @param mode Only the BUF_DiscardRamBuffer flag is checked as the BUF_ForceUpdate flag is considered always set for this function. By default mode is set to BUM_KeepRamBuffer. void updateBufferObject(EBufferObjectUpdateMode mode = BUM_KeepRamBuffer) { bufferObject()->setBufferData(usage(), (mode & BUF_DiscardRamBuffer) != 0); setBufferObjectDirty(false); } //! The 'normalized' parameter as used with glVertexAttribPointer() //! \sa //! - http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml void setNormalize(bool normalize) { mNormalize = normalize; } //! The 'normalized' parameter as used with glVertexAttribPointer() //! \sa //! - http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml bool normalize() const { return mNormalize; } //! How the data is interpreted by the OpenGL, see EVertexAttribInterpretation. void setInterpretation(EVertexAttribInterpretation behavior) { mInterpretation = behavior; } //! How the data is interpreted by the OpenGL, see EVertexAttribInterpretation. EVertexAttribInterpretation interpretation() const { return mInterpretation; } protected: ref mBufferObject; EBufferObjectUsage mBufferObjectUsage; bool mBufferObjectDirty; EVertexAttribInterpretation mInterpretation; bool mNormalize; }; //----------------------------------------------------------------------------- // Array //----------------------------------------------------------------------------- /** * The Array class is a template array used to conveniently manipulate data stored in a BufferObject. * \sa * * - ArrayAbstract * - vl::ArrayFloat1, vl::ArrayFloat2, vl::ArrayFloat3, vl::ArrayFloat4 * - vl::ArrayDouble1, vl::ArrayDouble2, vl::ArrayDouble3, vl::ArrayDouble4 * - vl::ArrayInt1, vl::ArrayInt2, vl::ArrayInt3, vl::ArrayInt4 * - vl::ArrayUInt1, vl::ArrayUInt2, vl::ArrayUInt3, vl::ArrayUInt4 * - vl::ArrayByte1, vl::ArrayByte2, vl::ArrayByte3, vl::ArrayByte4 * - vl::ArrayUByte1, vl::ArrayUByte2, vl::ArrayUByte3, vl::ArrayUByte4 * - vl::ArrayShort1, vl::ArrayShort2, vl::ArrayShort3, vl::ArrayShort4 * - vl::ArrayUShort1, vl::ArrayUShort2, vl::ArrayUShort3, vl::ArrayUShort4 * - vl::ArrayHFloat1, vl::ArrayHFloat2, vl::ArrayHFloat3, vl::ArrayHFloat4 * - vl::ArrayFixed1, vl::ArrayFixed2, vl::ArrayFixed3, vl::ArrayFixed4 * - vl::ArrayInt_2_10_10_10_REV1, ArrayInt_2_10_10_10_REV2, ArrayInt_2_10_10_10_REV3, ArrayInt_2_10_10_10_REV4 * - vl::ArrayUInt_2_10_10_10_REV1, ArrayUInt_2_10_10_10_REV2, ArrayUInt_2_10_10_10_REV3, ArrayUInt_2_10_10_10_REV4 */ template class Array: public ArrayAbstract { VL_INSTRUMENT_ABSTRACT_CLASS(vl::Array, ArrayAbstract) public: typedef T_Scalar scalar_type; typedef T_VectorType vector_type; static const size_t gl_size = T_GL_Size; static const GLenum gl_type = T_GL_Type; virtual size_t glSize() const { return T_GL_Size; } virtual GLenum glType() const { return T_GL_Type; } virtual size_t bytesPerVector() const { return sizeof(T_VectorType); } // --- void clear() { resize(0); bufferObject()->deleteBufferObject(); } void resize(size_t dim) { bufferObject()->resize(dim*bytesPerVector()); } size_t size() const { return bytesUsed() / bytesPerVector(); } size_t sizeBufferObject() const { return bufferObject() ? bufferObject()->byteCountBufferObject() / bytesPerVector() : 0; } size_t scalarCount() const { return size() * T_GL_Size; } size_t scalarCountBufferObject() const { return sizeBufferObject() * T_GL_Size; } // --- const T_VectorType* begin() const { return reinterpret_cast(ptr()); } T_VectorType* begin() { return reinterpret_cast(ptr()); } const T_VectorType* end() const { return (reinterpret_cast(ptr()))+size(); } T_VectorType* end() { return (reinterpret_cast(ptr()))+size(); } // --- T_VectorType& at(size_t i) { VL_CHECK(i(ptr())+i); } const T_VectorType& at(size_t i) const { VL_CHECK(i(ptr())+i); } T_VectorType& operator[](size_t i) { return at(i); } const T_VectorType& operator[](size_t i) const { return at(i); } // --- virtual ref createArray() const { return new Array; } virtual ref clone() const { ref arr = createArray()->template as(); VL_CHECK(arr); if (size()) { arr->resize(size()); memcpy(arr->ptr(), ptr(), bytesUsed()); } return arr; } // --- Sphere computeBoundingSphere() const { AABB aabb; const int count = T_GL_Size == 4 ? 3 : T_GL_Size; for(size_t i=0; i(&at(i)); for( int j=0; j(&at(i)); for( int j=0; j radius) radius = r; } return Sphere( center, sqrt(radius) ); } AABB computeBoundingBox() const { AABB aabb; const int count = T_GL_Size == 4 ? 3 : T_GL_Size; for(size_t i=0; i(&at(i)); for( int j=0; j(&at(i)); // read for( size_t j=0; j(&at(i)); // read for( size_t j=0; j(&at(vector_index)); for( size_t j=0; j(&at(vector_index)); const int count = T_GL_Size <= 3 ? T_GL_Size : 3; for( int j=0; j(&at(vector_index)); const int count = T_GL_Size <= 2 ? T_GL_Size : 2; for( int j=0; j(&at(a)); const T_Scalar* pb = reinterpret_cast(&at(b)); for( size_t i=0; i& vector) { resize(vector.size()); if (vector.empty()) return; else memcpy(ptr(),&vector[0],sizeof(vector[0])*vector.size()); } }; //----------------------------------------------------------------------------- // Array typedefs //----------------------------------------------------------------------------- //! An array of \p GLfloat class ArrayFloat1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayFloat1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayFloat1; } }; //! An array of vl::fvec2 class ArrayFloat2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayFloat2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayFloat2; } }; //! An array of vl::fvec3 class ArrayFloat3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayFloat3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayFloat3; } }; //! An array of vl::fvec4 class ArrayFloat4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayFloat4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayFloat4; } }; //! An array of \p GLdouble class ArrayDouble1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayDouble1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayDouble1; } }; //! An array of vl::dvec2 class ArrayDouble2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayDouble2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayDouble2; } }; //! An array of vl::dvec3 class ArrayDouble3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayDouble3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayDouble3; } }; //! An array of vl::dvec4 class ArrayDouble4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayDouble4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayDouble4; } }; //! An array of \p GLint class ArrayInt1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayInt1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayInt1; } }; //! An array of vl::ivec2 class ArrayInt2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayInt2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayInt2; } }; //! An array of vl::ivec3 class ArrayInt3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayInt3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayInt3; } }; //! An array of vl::ivec4 class ArrayInt4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayInt4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayInt4; } }; //! An array of \p GLuint class ArrayUInt1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUInt1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUInt1; } }; //! An array of vl::uvec2 class ArrayUInt2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUInt2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUInt2; } }; //! An array of vl::uvec3 class ArrayUInt3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUInt3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUInt3; } }; //! An array of vl::uvec4 class ArrayUInt4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUInt4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUInt4; } }; //! An array of \p GLbyte class ArrayByte1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayByte1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayByte1; } }; //! An array of vl::bvec2 class ArrayByte2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayByte2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayByte2; } }; //! An array of vl::bvec3 class ArrayByte3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayByte3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayByte3; } }; //! An array of vl::bvec4 class ArrayByte4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayByte4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayByte4; } }; //! An array of \p GLubyte class ArrayUByte1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUByte1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUByte1; } }; //! An array of vl::ubvec2 class ArrayUByte2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUByte2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUByte2; } }; //! An array of vl::ubvec3 class ArrayUByte3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUByte3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUByte3; } }; //! An array of vl::ubvec4 class ArrayUByte4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUByte4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUByte4; } }; //! An array of \p GLshort class ArrayShort1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayShort1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayShort1; } }; //! An array of vl::svec2 class ArrayShort2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayShort2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayShort2; } }; //! An array of vl::svec3 class ArrayShort3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayShort3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayShort3; } }; //! An array of vl::svec4 class ArrayShort4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayShort4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayShort4; } }; //! An array of \p GLushort class ArrayUShort1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUShort1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUShort1; } }; //! An array of vl::usvec2 class ArrayUShort2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUShort2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUShort2; } }; //! An array of vl::usvec3 class ArrayUShort3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUShort3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUShort3; } }; //! An array of vl::usvec4 class ArrayUShort4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUShort4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUShort4; } }; //! An array of \p GL_HALF_FLOAT class ArrayHFloat1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayHFloat1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayHFloat1; } }; //! A 2d array of GL_HALF_FLOAT vectors class ArrayHFloat2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayHFloat2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayHFloat2; } }; //! A 3d array of GL_HALF_FLOAT vectors class ArrayHFloat3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayHFloat3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayHFloat3; } }; //! A 4d array of GL_HALF_FLOAT vectors class ArrayHFloat4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayHFloat4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayHFloat4; } }; //! An array of \p GL_FIXED class ArrayFixed1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayFixed1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayFixed1; } }; //! An array 2d GL_FIXED vectors class ArrayFixed2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayFixed2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayFixed2; } }; //! An array 3d GL_FIXED vectors class ArrayFixed3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayFixed3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayFixed3; } }; //! An array 4d GL_FIXED vectors class ArrayFixed4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayFixed4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayFixed4; } }; //! An array of \p GL_INT_2_10_10_10_REV class ArrayInt_2_10_10_10_REV1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayInt_2_10_10_10_REV1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayInt_2_10_10_10_REV1; } }; //! A 2d array of GL_INT_2_10_10_10_REV vectors class ArrayInt_2_10_10_10_REV2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayInt_2_10_10_10_REV2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayInt_2_10_10_10_REV2; } }; //! A 3d array of GL_INT_2_10_10_10_REV vectors class ArrayInt_2_10_10_10_REV3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayInt_2_10_10_10_REV3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayInt_2_10_10_10_REV3; } }; //! A 4d array of GL_INT_2_10_10_10_REV vectors class ArrayInt_2_10_10_10_REV4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayInt_2_10_10_10_REV4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayInt_2_10_10_10_REV4; } }; //! An array of \p GL_UNSIGNED_INT_2_10_10_10_REV class ArrayUInt_2_10_10_10_REV1: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUInt_2_10_10_10_REV1, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUInt_2_10_10_10_REV1; } }; //! A 2d array of GL_UNSIGNED_INT_2_10_10_10_REV vectors class ArrayUInt_2_10_10_10_REV2: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUInt_2_10_10_10_REV2, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUInt_2_10_10_10_REV2; } }; //! A 3d array of GL_UNSIGNED_INT_2_10_10_10_REV vectors class ArrayUInt_2_10_10_10_REV3: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUInt_2_10_10_10_REV3, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUInt_2_10_10_10_REV3; } }; //! A 4d array of GL_UNSIGNED_INT_2_10_10_10_REV vectors class ArrayUInt_2_10_10_10_REV4: public Array { VL_INSTRUMENT_CLASS(vl::ArrayUInt_2_10_10_10_REV4, VL_GROUP(Array)) virtual ref createArray() const { return new ArrayUInt_2_10_10_10_REV4; } }; } #endif