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))