else
return strformat("%d bytes, %s", size, describe_enum(usage, ""));
}
+
+
+BufferBindingState::BufferBindingState():
+ buffer(0),
+ offset(0),
+ size(0)
+{ }
#include <string>
#include <vector>
+#include "autoconstptr.h"
#include "opengl.h"
struct ArrayState;
std::string describe() const;
};
+struct BufferBindingState
+{
+ AutoConstPtr<BufferState> buffer;
+ unsigned offset;
+ unsigned size;
+
+ BufferBindingState();
+};
+
#endif
active_tex(0),
client_active_tex(0),
array_buffer(0),
- element_buffer(0)
+ element_buffer(0),
+ uniform_buffer(0),
+ uniform_bind_points(64)
{
vertex_array.kind = GL_VERTEX_ARRAY;
normal_array.kind = GL_NORMAL_ARRAY;
decoder->glBindBuffer = glBindBuffer;
decoder->glBindBufferARB = glBindBuffer;
+ decoder->glBindBufferBase = glBindBufferBase;
+ decoder->glBindBufferRange = glBindBufferRange;
decoder->glBufferData = glBufferData;
decoder->glBufferDataARB = glBufferData;
decoder->glBufferSubData = glBufferSubData;
return i->second;
}
+const BufferBindingState &GlState::get_buffer_binding(GLenum target, unsigned index) const
+{
+ if(target==GL_UNIFORM_BUFFER)
+ return uniform_bind_points[index];
+ throw runtime_error("This buffer target does not have indexed binding points");
+}
+
const ArrayState &GlState::get_array(GLenum array) const
{
if(array==GL_VERTEX_ARRAY)
return texunits[active_tex].get_current_texture(target);
}
+BufferState *GlState::get_buffer_object(unsigned id)
+{
+ BufferMap::iterator i = buffers.find(id);
+ return (i==buffers.end() ? 0 : &i->second);
+}
+
BufferState *GlState::get_current_buffer(GLenum target)
{
if(target==GL_ARRAY_BUFFER)
return array_buffer;
else if(target==GL_ELEMENT_ARRAY_BUFFER)
return element_buffer;
+ else if(target==GL_UNIFORM_BUFFER)
+ return uniform_buffer;
+ return 0;
+}
+
+BufferBindingState *GlState::get_buffer_binding(GLenum target, unsigned index)
+{
+ if(target==GL_UNIFORM_BUFFER)
+ return &uniform_bind_points[index];
return 0;
}
array_buffer = buf;
else if(target==GL_ELEMENT_ARRAY_BUFFER)
element_buffer = buf;
+ else if(target==GL_UNIFORM_BUFFER)
+ uniform_buffer = buf;
}
ArrayState &GlState::get_attrib_array(unsigned index)
void GlState::glBindBuffer(void *user_data, GLenum target, unsigned id)
{ reinterpret_cast<GlState *>(user_data)->set_current_buffer(target, id); }
+void GlState::glBindBufferBase(void *user_data, GLenum target, unsigned index, unsigned id)
+{
+ if(BufferState *buffer = reinterpret_cast<GlState *>(user_data)->get_buffer_object(id))
+ glBindBufferRange(user_data, target, index, id, 0, buffer->size);
+}
+
+void GlState::glBindBufferRange(void *user_data, GLenum target, unsigned index, unsigned id, int offset, int size)
+{
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ if(BufferBindingState *binding = self->get_buffer_binding(target, index))
+ {
+ binding->buffer = self->get_buffer_object(id);
+ binding->offset = offset;
+ binding->size = size;
+ }
+}
+
void GlState::glBufferData(void *user_data, GLenum target, int size, const void *data, GLenum usage)
{
if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->get_current_buffer(target))
BufferMap buffers;
BufferState *array_buffer;
BufferState *element_buffer;
+ BufferState *uniform_buffer;
+ std::vector<BufferBindingState> uniform_bind_points;
ArrayState vertex_array;
ArrayState normal_array;
ArrayState color_array;
const BufferMap &get_buffers() const { return buffers; }
const BufferState &get_buffer(unsigned) const;
const BufferState *get_current_buffer(GLenum) const;
+ const BufferBindingState &get_buffer_binding(GLenum, unsigned) const;
const ArrayState &get_array(GLenum) const;
const ArrayState &get_texture_coord_array(unsigned) const;
const ArrayState &get_attrib_array(unsigned) const;
private:
bool &get_boolean_state(GLenum);
TextureState *get_current_texture(GLenum);
+ BufferState *get_buffer_object(unsigned);
BufferState *get_current_buffer(GLenum);
+ BufferBindingState *get_buffer_binding(GLenum, unsigned);
void set_current_texture(GLenum, unsigned);
void set_current_buffer(GLenum, unsigned);
ArrayState &get_attrib_array(unsigned);
static void glVertexAttribPointer(void *, unsigned, int, GLenum, unsigned char, int, const void *);
static void glBindBuffer(void *, GLenum, unsigned);
+ static void glBindBufferBase(void *, GLenum, unsigned, unsigned);
+ static void glBindBufferRange(void *, GLenum, unsigned, unsigned, int, int);
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 *);
printf(" GL_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0));
buf = glstate.get_current_buffer(GL_ELEMENT_ARRAY_BUFFER);
printf(" GL_ELEMENT_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0));
+ buf = glstate.get_current_buffer(GL_UNIFORM_BUFFER);
+ printf(" GL_UNIFORM_BUFFER: %d\n", (buf ? buf->id : 0));
+ for(unsigned i=0; i<64; ++i)
+ {
+ const BufferBindingState &binding = glstate.get_buffer_binding(GL_UNIFORM_BUFFER, i);
+ if(binding.buffer)
+ printf(" %d: %d (%d bytes at %d)\n", i, binding.buffer->id, binding.size, binding.offset);
+ }
}
else
throw runtime_error("Invalid or missing argument");