From: Mikko Rasa Date: Sun, 22 Dec 2013 00:15:06 +0000 (+0200) Subject: Simplify VAO setup code X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=126ac7ca4053b765eab1473d2865bce728ef2428 Simplify VAO setup code Previously buffer binding semantics caused complications, as index buffer was unbound while a mesh was bound so batches couldn't be updated. Now that buffers behave better with bounds meshes, batches can take care of themselves again. Triggering the setup from bind() instead of draw() gets rid of another bunch of complications, since it will only be called when the VAO is going to be actually used. --- diff --git a/source/mesh.cpp b/source/mesh.cpp index 45b022fa..45c550a0 100644 --- a/source/mesh.cpp +++ b/source/mesh.cpp @@ -16,7 +16,7 @@ Mesh::Mesh(): ibuf(0), vao_id(0), defer_buffers(true), - dirty(0), + dirty(false), winding(0) { } @@ -26,7 +26,7 @@ Mesh::Mesh(const VertexFormat &f): ibuf(0), vao_id(0), defer_buffers(true), - dirty(2), + dirty(true), winding(0) { } @@ -74,52 +74,29 @@ void Mesh::create_buffers() glGenVertexArrays(1, &vao_id); } -void Mesh::refresh() const +void Mesh::setup_vao() const { - if(!vbuf) - return; + Bind bind_vbuf(vbuf, ARRAY_BUFFER); - vertices.refresh(); - if(dirty) + const VertexFormat &fmt = vertices.get_format(); + unsigned stride = get_stride(fmt)*sizeof(float); + float *ptr = 0; + for(const unsigned char *c=fmt.begin(); c!=fmt.end(); ++c) { - if(dirty&1) - { - for(list::const_iterator i=batches.begin(); i!=batches.end(); ++i) - i->refresh(); - } - - if(dirty&2) - { - 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; - for(const unsigned char *c=fmt.begin(); c!=fmt.end(); ++c) - { - unsigned t = get_component_type(*c); - if(t>=get_component_type(ATTRIB1)) - t -= get_component_type(ATTRIB1); - unsigned sz = get_component_size(*c); - if(*c==COLOR4_UBYTE) - glVertexAttribPointer(t, 4, GL_UNSIGNED_BYTE, true, stride, ptr); - else - glVertexAttribPointer(t, sz, GL_FLOAT, false, stride, ptr); - glEnableVertexAttribArray(t); - ptr += sz; - } - glBindBuffer(ELEMENT_ARRAY_BUFFER, ibuf->get_id()); - - if(bind_here) - glBindVertexArray(0); - } - - dirty = 0; + unsigned t = get_component_type(*c); + if(t>=get_component_type(ATTRIB1)) + t -= get_component_type(ATTRIB1); + unsigned sz = get_component_size(*c); + if(*c==COLOR4_UBYTE) + glVertexAttribPointer(t, 4, GL_UNSIGNED_BYTE, true, stride, ptr); + else + glVertexAttribPointer(t, sz, GL_FLOAT, false, stride, ptr); + glEnableVertexAttribArray(t); + ptr += sz; } + glBindBuffer(ELEMENT_ARRAY_BUFFER, ibuf->get_id()); + + dirty = false; } unsigned Mesh::get_n_vertices() const @@ -160,8 +137,6 @@ void Mesh::draw() const if(cur && cur!=this) throw invalid_operation("Mesh::draw"); - refresh(); - if(!current()) vertices.apply(); Bind bind_ibuf(ibuf, ELEMENT_ARRAY_BUFFER); @@ -173,8 +148,6 @@ void Mesh::draw() const void Mesh::draw(Renderer &renderer) const { - refresh(); - renderer.set_mesh(this); renderer.set_element_buffer(ibuf); renderer.set_winding_test(winding); @@ -190,7 +163,12 @@ void Mesh::bind() const if(!vao_id) unbind(); else if(set_current(this)) + { glBindVertexArray(vao_id); + vertices.refresh(); + if(dirty) + setup_vao(); + } } void Mesh::unbind() @@ -217,7 +195,7 @@ void Mesh::Loader::vertices(const vector &c) for(vector::const_iterator i=c.begin(); i!=c.end(); ++i) fmt = (fmt, *i); obj.vertices.reset(fmt); - obj.dirty |= 2; + obj.dirty = true; load_sub(obj.vertices); } diff --git a/source/mesh.h b/source/mesh.h index ba21f256..730b724c 100644 --- a/source/mesh.h +++ b/source/mesh.h @@ -39,7 +39,7 @@ private: Buffer *ibuf; unsigned vao_id; bool defer_buffers; - mutable unsigned char dirty; + mutable bool dirty; const WindingTest *winding; public: @@ -51,7 +51,7 @@ public: void use_buffers(bool); private: void create_buffers(); - void refresh() const; + void setup_vao() const; public: const VertexArray &get_vertices() const { return vertices; }