This simplifies the internal update operations.
if(Buffer *ibuf = get_buffer())
{
- bool have_vao = Mesh::current();
- const Buffer *old_ibuf = 0;
- if(!have_vao)
- {
- old_ibuf = Buffer::current(ELEMENT_ARRAY_BUFFER);
- ibuf->bind_to(ELEMENT_ARRAY_BUFFER);
- }
+ BindRestore _bind_ibuf(ibuf, ELEMENT_ARRAY_BUFFER);
if(dirty)
update_buffer();
glDrawRangeElements(prim_type, min_index, max_index, size(), data_type, reinterpret_cast<void *>(get_offset()));
- if(!have_vao)
- {
- if(old_ibuf)
- old_ibuf->bind_to(ELEMENT_ARRAY_BUFFER);
- else
- Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
- }
}
else
glDrawRangeElements(prim_type, min_index, max_index, size(), data_type, &data[0]);
{
if(t!=type)
require_buffer_type(t);
- // Don't change the binding in a mesh's vertex array object
- if(t==ELEMENT_ARRAY_BUFFER && Mesh::current())
- throw invalid_operation("Buffer::bind_to(ELEMENT_ARRAY_BUFFER)");
+ if(t==ELEMENT_ARRAY_BUFFER)
+ if(const Mesh *m = Mesh::current())
+ {
+ // Don't change the binding in a mesh's vertex array object
+ if(this==m->get_index_buffer())
+ return;
+ throw invalid_operation("Buffer::bind_to(ELEMENT_ARRAY_BUFFER)");
+ }
if(set_current(t, this))
glBindBuffer(t, id);
}
+const Buffer *Buffer::current(BufferType t)
+{
+ if(t==ELEMENT_ARRAY_BUFFER)
+ if(const Mesh *m = Mesh::current())
+ return m->get_index_buffer();
+ return binding(t);
+}
+
void Buffer::unbind_from(BufferType type)
{
if(type==ELEMENT_ARRAY_BUFFER && Mesh::current())
/** Unbinds the buffer from its default slot. */
void unbind() const { unbind_from(type); }
- static const Buffer *current(BufferType t) { return binding(t); }
+ static const Buffer *current(BufferType);
static void unbind_from(BufferType);
private:
static const Buffer *&binding(BufferType);
{
if(dirty&1)
{
- unbind();
for(list<Batch>::const_iterator i=batches.begin(); i!=batches.end(); ++i)
i->refresh();
}
if(dirty&2)
{
- glBindVertexArray(vao_id);
Bind bind_vbuf(vbuf, ARRAY_BUFFER);
+ bool bind_here = !current();
+ if(bind_here)
+ glBindVertexArray(vao_id);
+
const VertexFormat &fmt = vertices.get_format();
unsigned stride = get_stride(fmt)*sizeof(float);
float *ptr = 0;
ptr += sz;
}
glBindBuffer(ELEMENT_ARRAY_BUFFER, ibuf->get_id());
- glBindVertexArray(0);
+
+ if(bind_here)
+ glBindVertexArray(0);
}
dirty = 0;
called. Thus unbind won't try to call a null function either. */
if(!vao_id)
unbind();
- else
- {
- if(Buffer::current(ELEMENT_ARRAY_BUFFER))
- {
- unbind();
- Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
- }
- if(set_current(this))
- glBindVertexArray(vao_id);
- }
+ else if(set_current(this))
+ glBindVertexArray(vao_id);
}
void Mesh::unbind()
public:
const VertexArray &get_vertices() const { return vertices; }
+ const Buffer *get_index_buffer() const { return ibuf; }
unsigned get_n_vertices() const;
float *modify_vertex(unsigned);