]> git.tdb.fi Git - libs/gl.git/blobdiff - source/mesh.cpp
Avoid segfault for trying to refresh a Mesh with no buffers
[libs/gl.git] / source / mesh.cpp
index c9819ae91c0e60dcec38f18febe5ffeb1747f94f..45b022facc1edb8a673c4ea5e6d59485bff2b209 100644 (file)
@@ -1,6 +1,7 @@
 #include <msp/gl/extensions/arb_vertex_array_object.h>
 #include <msp/gl/extensions/arb_vertex_shader.h>
 #include "buffer.h"
+#include "error.h"
 #include "mesh.h"
 #include "renderer.h"
 
@@ -75,21 +76,26 @@ void Mesh::create_buffers()
 
 void Mesh::refresh() const
 {
+       if(!vbuf)
+               return;
+
        vertices.refresh();
        if(dirty)
        {
                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;
@@ -107,7 +113,9 @@ void Mesh::refresh() const
                                ptr += sz;
                        }
                        glBindBuffer(ELEMENT_ARRAY_BUFFER, ibuf->get_id());
-                       glBindVertexArray(0);
+
+                       if(bind_here)
+                               glBindVertexArray(0);
                }
 
                dirty = 0;
@@ -148,22 +156,19 @@ void Mesh::set_winding(const WindingTest *w)
 
 void Mesh::draw() const
 {
+       const Mesh *cur = current();
+       if(cur && cur!=this)
+               throw invalid_operation("Mesh::draw");
+
        refresh();
 
        if(!current())
-       {
                vertices.apply();
-               if(ibuf)
-                       ibuf->bind_to(ELEMENT_ARRAY_BUFFER);
-       }
-
+       Bind bind_ibuf(ibuf, ELEMENT_ARRAY_BUFFER);
        Bind bind_winding(winding);
 
        for(list<Batch>::const_iterator i=batches.begin(); i!=batches.end(); ++i)
                i->draw();
-
-       if(!current() && ibuf)
-               Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
 }
 
 void Mesh::draw(Renderer &renderer) const
@@ -184,16 +189,8 @@ void Mesh::bind() const
        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()