*/
#include <msp/strings/formatter.h>
+#include "arraysize.h"
#include "arraystate.h"
#include "bufferstate.h"
#include "enums.h"
arrays.insert(place, array);
}
+void BufferContent::update_elements(GLenum type)
+{
+ if(arrays.empty())
+ {
+ Array array;
+ array.kind = GL_ELEMENT_ARRAY_BUFFER;
+ array.type = type;
+ arrays.push_back(array);
+ stride = typesize(type);
+ }
+ else if(arrays.size()>1 || arrays.front().kind!=GL_ELEMENT_ARRAY_BUFFER)
+ consistent = false;
+ else
+ {
+ if(arrays.front().type!=type)
+ consistent = false;
+ arrays.front().type = type;
+ stride = typesize(type);
+ }
+}
+
string BufferContent::describe() const
{
if(arrays.empty())
kind = 'C';
else if(i->kind==GL_TEXTURE_COORD_ARRAY && i->index==0)
kind = 'T';
+ else if(i->kind==GL_ELEMENT_ARRAY_BUFFER)
+ kind = 'E';
char type[3] = { '?', 0, 0 };
if(i->type==GL_FLOAT)
}
+BufferContent::Array::Array():
+ kind(GL_NONE),
+ index(0),
+ size(1),
+ type(GL_NONE),
+ offset(0)
+{ }
+
BufferContent::Array::Array(const ArrayState &a):
kind(a.kind),
index(a.index),
BufferState::BufferState():
+ id(0),
+ target(0),
usage(GL_STATIC_DRAW),
size(0),
data(0)
string BufferState::describe() const
{
if(content.stride)
- return format("%s, %d vertices (%d bytes), %s",
- content.describe(), size/content.stride, size, describe_enum(usage, ""));
+ {
+ const char *what = (content.arrays.front().kind==GL_ELEMENT_ARRAY_BUFFER ? "indices" : "vertices");
+ return format("%s, %d %s (%d bytes), %s",
+ content.describe(), size/content.stride, what, size, describe_enum(usage, ""));
+ }
else
return format("%d bytes, %s", size, describe_enum(usage, ""));
}
GLenum type;
int offset;
+ Array();
Array(const ArrayState &);
};
BufferContent();
void update(const ArrayState &);
+ void update_elements(GLenum);
std::string describe() const;
};
decoder->glBufferSubDataARB = glBufferSubData;
decoder->glDeleteBuffers = glDeleteBuffers;
decoder->glDeleteBuffersARB = glDeleteBuffers;
+
+ decoder->glDrawElements = glDrawElements;
+ decoder->glDrawRangeElements = glDrawRangeElements;
+ decoder->glDrawRangeElementsEXT = glDrawRangeElements;
}
GlState::~GlState()
for(int i=0; i<count; ++i)
reinterpret_cast<GlState *>(user_data)->buffers.erase(ids[i]);
}
+
+void GlState::glDrawElements(void *user_data, GLenum, int, GLenum type, const void *)
+{
+ if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->element_buffer)
+ buf->content.update_elements(type);
+}
+
+void GlState::glDrawRangeElements(void *user_data, GLenum, unsigned, unsigned, int, GLenum type, const void *)
+{
+ if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->element_buffer)
+ buf->content.update_elements(type);
+}
static void glBufferData(void *, GLenum, int, const void *, GLenum);
static void glBufferSubData(void *, GLenum, int, int, const void *);
static void glDeleteBuffers(void *, int, const unsigned *);
+
+ static void glDrawElements(void *, GLenum, int, GLenum, const void *);
+ static void glDrawRangeElements(void *, GLenum, unsigned, unsigned, int, GLenum, const void *);
};
#endif
IO::print("Buffer %d:\n", id);
IO::print(" Size: %d bytes\n", buf.size);
IO::print(" Usage: %s\n", describe_enum(buf.usage, ""));
- if(buf.content.stride)
+ if(buf.content.arrays.size()==1 && buf.content.arrays.front().kind==GL_ELEMENT_ARRAY_BUFFER)
+ {
+ const BufferContent::Array &array = buf.content.arrays.front();
+ IO::print(" Arrays:\n");
+ IO::print(" 0: Element indices, 1 %s\n", describe_enum(array.type, "DataType"));
+
+ IO::print(" Data:\n");
+ unsigned width = 1+buf.content.stride*2;
+ string fmt = format(" %%%du", width);
+ unsigned n_elems = buf.size/buf.content.stride;
+ string line;
+ const char *ptr = buf.data;
+ for(unsigned i=0; i<n_elems; ++i)
+ {
+ if(line.empty())
+ line = " ";
+
+ if(array.type==GL_UNSIGNED_BYTE)
+ line += format(fmt, *(reinterpret_cast<unsigned char *>(ptr)+i));
+ else if(array.type==GL_UNSIGNED_SHORT)
+ line += format(fmt, *(reinterpret_cast<unsigned short *>(ptr)+i));
+ else if(array.type==GL_UNSIGNED_INT)
+ line += format(fmt, *(reinterpret_cast<unsigned *>(ptr)+i));
+
+ if(line.size()+1+width>79)
+ {
+ IO::print("%s\n", line);
+ line.clear();
+ }
+ }
+
+ if(!line.empty())
+ IO::print("%s\n", line);
+ }
+ else if(buf.content.stride)
{
IO::print(" Stride: %d bytes\n", buf.content.stride);