+unsigned VertexArray::get_data_size() const
+{
+ return data.size()*sizeof(float);
+}
+
+void VertexArray::bind() const
+{
+ if(format.empty())
+ throw invalid_operation("VertexArray::apply");
+ // Don't mess up the vertex array object of a mesh
+ if(Mesh::current())
+ throw invalid_operation("VertexArray::apply");
+
+ const VertexArray *old = current();
+ /* If the array has been modified, apply it even if it was the last one to
+ be applied. This is necessary to get the data updated to vertex buffer, and
+ to resync things after a format change. Radeon drivers also have some
+ problems with modifying vertex arrays without re-setting the pointers. */
+ if(!set_current(this) && !dirty)
+ return;
+
+ Buffer *vbuf = get_buffer();
+ Bind _bind_vbuf(vbuf, ARRAY_BUFFER);
+ if(vbuf && dirty)
+ update_buffer();
+
+ const float *base = (vbuf ? reinterpret_cast<float *>(get_offset()) : &data[0]);
+ unsigned stride_bytes = stride*sizeof(float);
+ apply_arrays(&arrays, (old ? &old->arrays : 0), base, stride_bytes);
+}
+
+void VertexArray::apply_arrays(const vector<Array> *arrays, const vector<Array> *old_arrays, const float *base, unsigned stride_bytes)
+{
+ unsigned active_tex = 0;
+ unsigned n_arrays = arrays ? arrays->size() : 0;
+ if(old_arrays)
+ n_arrays = max<unsigned>(n_arrays, old_arrays->size());
+ for(unsigned i=0; i<n_arrays; ++i)