+VertexFormat::VertexFormat():
+ data(0)
+{ }
+
+VertexFormat::VertexFormat(VertexComponent c):
+ data(new unsigned char[8])
+{
+ data[0] = 1;
+ data[1] = c;
+}
+
+VertexFormat::VertexFormat(const VertexFormat &f):
+ data(0)
+{
+ if(f.data)
+ {
+ data = new unsigned char[(f.data[0]&~7)+8];
+ memcpy(data, f.data, f.data[0]+1);
+ }
+}
+
+VertexFormat &VertexFormat::operator=(const VertexFormat &f)
+{
+ delete[] data;
+ if(f.data)
+ {
+ data = new unsigned char[(f.data[0]&~7)+8];
+ memcpy(data, f.data, f.data[0]+1);
+ }
+ else
+ data = 0;
+
+ return *this;
+}
+
+VertexFormat::~VertexFormat()
+{
+ delete[] data;
+}
+
+unsigned VertexFormat::stride() const
+{
+ unsigned s = 0;
+ for(const unsigned char *i=begin(); i!=end(); ++i)
+ s += (*i&3)+1;
+ return s;
+}
+
+int VertexFormat::offset(VertexComponent comp, unsigned index) const
+{
+ if((comp<TEXCOORD1 && index>0) || (comp<ATTRIB1 && index>=8) || index>=53)
+ throw out_of_range("VertexFormat::offset");
+
+ unsigned type = (comp>>2)+index;
+ unsigned size = comp&3;
+ unsigned offs = 0;
+ for(const unsigned char *i=begin(); i!=end(); ++i)
+ {
+ if(static_cast<unsigned>(*i>>2)==type)
+ {
+ if((*i&3)>=size)
+ return offs;
+ else
+ return -1;
+ }
+ else
+ offs += (*i&3)+1;
+ }
+
+ return -1;
+}
+
+VertexFormat operator,(const VertexFormat &f, VertexComponent c)