+
+vector<const BufferRange *> BufferRange::bound_uniform;
+
+BufferRange::BufferRange(Buffer &b, unsigned o, unsigned s):
+ buffer(b),
+ offset(o),
+ size(s)
+{
+ if(o>buffer.get_size() || o+s>buffer.get_size())
+ throw out_of_range("BufferRange::BufferRange");
+}
+
+void BufferRange::data(const void *d)
+{
+ buffer.sub_data(offset, size, d);
+}
+
+void BufferRange::bind_to(BufferType t, unsigned i)
+{
+ if(t!=buffer.type)
+ Buffer::require_buffer_type(t);
+ // Intentionally using bitwise | to avoid short-circuiting
+ if(Buffer::set_current(t, &buffer) | set_current(t, i, this))
+ glBindBufferRange(t, i, buffer.id, offset, size);
+}
+
+void BufferRange::unbind_from(BufferType t, unsigned i)
+{
+ if(set_current(t, i, 0))
+ {
+ Buffer::set_current(t, 0);
+ glBindBufferBase(t, i, 0);
+ }
+}
+
+const BufferRange *&BufferRange::binding(BufferType type, unsigned index)