]> git.tdb.fi Git - gldbg.git/blobdiff - source/bufferstate.cpp
Track vertex array state
[gldbg.git] / source / bufferstate.cpp
index 9b1c38f4dcd95f3b801c4f76733fde3b2b39d566..356e82b5ac3de9469b748338d852956f010bb808 100644 (file)
 /* $Id$
 
 This file is part of gldbg
-Copyright © 2009  Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the GPL
 */
 
 #include <msp/strings/formatter.h>
+#include "arraystate.h"
 #include "bufferstate.h"
 #include "enums.h"
 
 using namespace std;
 using namespace Msp;
 
+BufferContent::BufferContent():
+       consistent(true),
+       stride(0)
+{ }
+
+void BufferContent::update(const ArrayState &array)
+{
+       if(array.stride!=stride)
+               consistent = false;
+
+       stride = array.stride;
+
+       for(vector<Array>::iterator i=arrays.begin(); i!=arrays.end(); ++i)
+               if(i->kind==array.kind && i->index==array.index)
+               {
+                       if(array.size!=i->size || array.type!=i->type || array.pointer!=i->offset)
+                       {
+                               consistent = false;
+                               arrays.erase(i);
+                       }
+                       else
+                               return;
+
+
+                       break;
+               }
+
+       vector<Array>::iterator place = arrays.end();
+       for(vector<Array>::iterator i=arrays.begin(); i!=arrays.end(); ++i)
+               if(i->offset>array.pointer)
+               {
+                       place = i;
+                       break;
+               }
+
+       arrays.insert(place, array);
+}
+
+string BufferContent::describe() const
+{
+       if(arrays.empty())
+               return "(unknown)";
+
+       string result;
+       for(vector<Array>::const_iterator i=arrays.begin(); i!=arrays.end(); ++i)
+       {
+               char kind = '?';
+               if(i->kind==GL_VERTEX_ARRAY)
+                       kind = 'V';
+               else if(i->kind==GL_NORMAL_ARRAY)
+                       kind = 'N';
+               else if(i->kind==GL_COLOR_ARRAY)
+                       kind = 'C';
+               else if(i->kind==GL_TEXTURE_COORD_ARRAY && i->index==0)
+                       kind = 'T';
+
+               char type[3] = { '?', 0, 0 };
+               if(i->type==GL_FLOAT)
+                       type[0] = 'F';
+               else if(i->type==GL_DOUBLE)
+                       type[0] = 'D';
+               else if(i->type==GL_INT || i->type==GL_UNSIGNED_INT)
+                       type[0] = 'I';
+               else if(i->type==GL_SHORT || i->type==GL_UNSIGNED_SHORT)
+                       type[0] = 'S';
+               else if(i->type==GL_BYTE || i->type==GL_UNSIGNED_BYTE)
+                       type[0] = 'B';
+
+               if(i->type==GL_UNSIGNED_INT || i->type==GL_UNSIGNED_SHORT || i->type==GL_UNSIGNED_BYTE)
+               {
+                       type[1] = type[0];
+                       type[0] = 'U';
+               }
+
+               if(!result.empty())
+                       result += '_';
+               result += format("%c%d%s", kind, i->size, type);
+       }
+
+       return result;
+}
+
+
+BufferContent::Array::Array(const ArrayState &a):
+       kind(a.kind),
+       index(a.index),
+       size(a.size),
+       type(a.type),
+       offset(a.pointer)
+{ }
+
+
 BufferState::BufferState():
        usage(GL_STATIC_DRAW),
        size(0),
@@ -26,11 +119,12 @@ void BufferState::set_data(unsigned sz, const void *ptr, GLenum use)
        data = new char[size];
        if(ptr)
                set_sub_data(0, size, ptr);
+       content = BufferContent();
 }
 
 void BufferState::set_sub_data(unsigned off, unsigned sz, const void *ptr)
 {
-       if(data && off+sz<size)
+       if(data && off+sz<=size)
        {
                const char *cptr = reinterpret_cast<const char *>(ptr);
                copy(cptr, cptr+sz, data+off);
@@ -39,5 +133,9 @@ void BufferState::set_sub_data(unsigned off, unsigned sz, const void *ptr)
 
 string BufferState::describe() const
 {
-       return format("%d bytes, %s", size, describe_enum(usage, ""));
+       if(content.stride)
+               return format("%s, %d vertices (%d bytes), %s",
+                       content.describe(), size/content.stride, size, describe_enum(usage, ""));
+       else
+               return format("%d bytes, %s", size, describe_enum(usage, ""));
 }