decoder->glEnableClientState = glEnableClientState;
decoder->glDisableClientState = glDisableClientState;
- decoder->glEnableVertexAttribArray = glEnableVertexAttribArray;
- decoder->glEnableVertexAttribArrayARB = glEnableVertexAttribArray;
- decoder->glDisableVertexAttribArray = glDisableVertexAttribArray;
- decoder->glDisableVertexAttribArrayARB = glDisableVertexAttribArray;
decoder->glColor3ub = wrap_normalized<GLubyte, glColor3f>;
decoder->glColor3ubv = wrap_array<GLubyte, wrap_normalized<GLubyte, glColor3f> >;
decoder->glNormal3f = glNormal3f;
decoder->glNormal3fv = wrap_array<float, glNormal3f>;
- decoder->glActiveTexture = glActiveTexture;
- decoder->glActiveTextureARB = glActiveTexture;
- decoder->glBindTexture = glBindTexture;
- decoder->glTexImage2D = glTexImage2D;
- decoder->glTexParameteri = glTexParameteri;
- decoder->glTexParameteriv = glTexParameteriv;
- decoder->glDeleteTextures = glDeleteTextures;
-
decoder->glVertexPointer = glVertexPointer;
decoder->glNormalPointer = glNormalPointer;
decoder->glColorPointer = glColorPointer;
decoder->glClientActiveTexture = glClientActiveTexture;
decoder->glClientActiveTextureARB = glClientActiveTexture;
decoder->glTexCoordPointer = glTexCoordPointer;
+ decoder->glEnableVertexAttribArray = glEnableVertexAttribArray;
+ decoder->glEnableVertexAttribArrayARB = glEnableVertexAttribArray;
+ decoder->glDisableVertexAttribArray = glDisableVertexAttribArray;
+ decoder->glDisableVertexAttribArrayARB = glDisableVertexAttribArray;
decoder->glVertexAttribPointer = glVertexAttribPointer;
decoder->glVertexAttribPointerARB = glVertexAttribPointer;
+ decoder->glDrawElements = glDrawElements;
+ decoder->glDrawRangeElements = glDrawRangeElements;
+ decoder->glDrawRangeElementsEXT = glDrawRangeElements;
+
decoder->glBindBuffer = glBindBuffer;
decoder->glBindBufferARB = glBindBuffer;
decoder->glBindBufferBase = glBindBufferBase;
decoder->glDeleteBuffers = glDeleteBuffers;
decoder->glDeleteBuffersARB = glDeleteBuffers;
- decoder->glDrawElements = glDrawElements;
- decoder->glDrawRangeElements = glDrawRangeElements;
- decoder->glDrawRangeElementsEXT = glDrawRangeElements;
+ decoder->glActiveTexture = glActiveTexture;
+ decoder->glActiveTextureARB = glActiveTexture;
+ decoder->glBindTexture = glBindTexture;
+ decoder->glTexImage2D = glTexImage2D;
+ decoder->glTexParameteri = glTexParameteri;
+ decoder->glTexParameteriv = glTexParameteriv;
+ decoder->glDeleteTextures = glDeleteTextures;
decoder->glCreateShader = glCreateShader;
decoder->glCreateShaderObjectARB = glCreateShader;
return gldecoder_decode(decoder, data, len);
}
-const TextureState &GlState::get_texture(unsigned id) const
+// Boolean state
+
+bool &GlState::get_boolean_state(GLenum state)
{
- TextureMap::const_iterator i = textures.find(id);
- if(i==textures.end())
- throw runtime_error("Unknown texture");
- return i->second;
+ if(state==GL_VERTEX_ARRAY)
+ return vertex_array.enabled;
+ else if(state==GL_NORMAL_ARRAY)
+ return normal_array.enabled;
+ else if(state==GL_COLOR_ARRAY)
+ return color_array.enabled;
+ else if(state==GL_TEXTURE_COORD_ARRAY)
+ return texcoord_arrays[client_active_tex].enabled;
+
+ static bool dummy;
+ return dummy;
}
-const BufferState &GlState::get_buffer(unsigned id) const
+void GlState::glEnableClientState(void *user_data, GLenum state)
{
- BufferMap::const_iterator i = buffers.find(id);
- if(i==buffers.end())
- throw runtime_error("Unknown buffer");
- return i->second;
+ reinterpret_cast<GlState *>(user_data)->get_boolean_state(state) = true;
}
-const BufferBindingState &GlState::get_buffer_binding(GLenum target, unsigned index) const
+void GlState::glDisableClientState(void *user_data, GLenum state)
{
- if(target==GL_UNIFORM_BUFFER)
- return uniform_bind_points[index];
- throw runtime_error("This buffer target does not have indexed binding points");
+ reinterpret_cast<GlState *>(user_data)->get_boolean_state(state) = false;
}
-const ArrayState &GlState::get_array(GLenum array) const
+// Vertex attributes
+
+void GlState::glColor3f(void *user_data, float r, float g, float b)
{
- if(array==GL_VERTEX_ARRAY)
- return vertex_array;
- else if(array==GL_NORMAL_ARRAY)
- return normal_array;
- else if(array==GL_COLOR_ARRAY)
- return color_array;
- else if(array==GL_TEXTURE_COORD_ARRAY)
- return texcoord_arrays[client_active_tex];
- else
- throw logic_error("Invalid array");
+ glColor4f(user_data, r, g, b, 1.0f);
}
-const ArrayState &GlState::get_texture_coord_array(unsigned index) const
+void GlState::glColor4f(void *user_data, float r, float g, float b, float a)
{
- return texcoord_arrays[index];
+ Vector4 &color = reinterpret_cast<GlState *>(user_data)->color;
+ color.r = r;
+ color.g = g;
+ color.b = b;
+ color.a = a;
}
-const ArrayState &GlState::get_attrib_array(unsigned index) const
+void GlState::glNormal3f(void *user_data, float x, float y, float z)
{
- map<unsigned, ArrayState>::const_iterator i = attrib_arrays.find(index);
+ Vector3 &normal = reinterpret_cast<GlState *>(user_data)->normal;
+ normal.x = x;
+ normal.y = y;
+ normal.z = z;
+}
+
+void GlState::glTexCoord1f(void *user_data, float s)
+{
+ glTexCoord4f(user_data, s, 0.0f, 0.0f, 1.0f);
+}
+
+void GlState::glTexCoord2f(void *user_data, float s, float t)
+{
+ glTexCoord4f(user_data, s, t, 0.0f, 1.0f);
+}
+
+void GlState::glTexCoord3f(void *user_data, float s, float t, float p)
+{
+ glTexCoord4f(user_data, s, t, p, 1.0f);
+}
+
+void GlState::glTexCoord4f(void *user_data, float s, float t, float p, float q)
+{
+ unsigned index = reinterpret_cast<GlState *>(user_data)->active_tex;
+ glMultiTexCoord4f(user_data, index, s, t, p, q);
+}
+
+void GlState::glMultiTexCoord4f(void *user_data, unsigned index, float s, float t, float p, float q)
+{
+ Vector4 &texcoord = reinterpret_cast<GlState *>(user_data)->texcoord[index];
+ texcoord.s = s;
+ texcoord.t = t;
+ texcoord.p = p;
+ texcoord.q = q;
+}
+
+// Vertex arrays
+
+ArrayState &GlState::get_attrib_array(unsigned index)
+{
+ map<unsigned, ArrayState>::iterator i = attrib_arrays.find(index);
if(i!=attrib_arrays.end())
return i->second;
- // XXX Return a dummy?
- throw runtime_error("Unknown attribute array");
+ ArrayState &array = attrib_arrays[index];
+ array.index = index;
+
+ return array;
}
-const ShaderState &GlState::get_shader(unsigned id) const
+void GlState::glVertexPointer(void *user_data, int size, GLenum type, int stride, const void *data)
{
- ShaderMap::const_iterator i = shaders.find(id);
- if(i==shaders.end())
- throw runtime_error("Unknown shader");
- return i->second;
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ self->vertex_array.set(size, type, false, stride, self->array_buffer, reinterpret_cast<long>(data));
}
-const ProgramState &GlState::get_program(unsigned id) const
+void GlState::glNormalPointer(void *user_data, GLenum type, int stride, const void *data)
{
- ProgramMap::const_iterator i = programs.find(id);
- if(i==programs.end())
- throw runtime_error("Unknown program");
- return i->second;
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ self->normal_array.set(3, type, true, stride, self->array_buffer, reinterpret_cast<long>(data));
}
-const BufferState *GlState::get_current_buffer(GLenum target) const
+void GlState::glColorPointer(void *user_data, int size, GLenum type, int stride, const void *data)
{
- return const_cast<GlState *>(this)->get_current_buffer(target);
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ self->color_array.set(size, type, true, stride, self->array_buffer, reinterpret_cast<long>(data));
}
-bool &GlState::get_boolean_state(GLenum state)
+void GlState::glClientActiveTexture(void *user_data, unsigned index)
{
- if(state==GL_VERTEX_ARRAY)
- return vertex_array.enabled;
- else if(state==GL_NORMAL_ARRAY)
- return normal_array.enabled;
- else if(state==GL_COLOR_ARRAY)
- return color_array.enabled;
- else if(state==GL_TEXTURE_COORD_ARRAY)
- return texcoord_arrays[client_active_tex].enabled;
+ reinterpret_cast<GlState *>(user_data)->client_active_tex = index-GL_TEXTURE0;
+}
- static bool dummy;
- return dummy;
+void GlState::glTexCoordPointer(void *user_data, int size, GLenum type, int stride, const void *data)
+{
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ self->texcoord_arrays[self->client_active_tex].set(size, type, false, stride, self->array_buffer, reinterpret_cast<long>(data));
}
-TextureState *GlState::get_current_texture(GLenum target)
+void GlState::glEnableVertexAttribArray(void *user_data, unsigned index)
{
- return texunits[active_tex].get_current_texture(target);
+ reinterpret_cast<GlState *>(user_data)->attrib_arrays[index].enabled = true;
}
-BufferState *GlState::get_buffer_object(unsigned id)
+void GlState::glDisableVertexAttribArray(void *user_data, unsigned index)
{
- BufferMap::iterator i = buffers.find(id);
- return (i==buffers.end() ? 0 : &i->second);
+ reinterpret_cast<GlState *>(user_data)->attrib_arrays[index].enabled = false;
}
-BufferState *GlState::get_current_buffer(GLenum target)
+void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, GLenum type, unsigned char norm, int stride, const void *data)
{
- 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;
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ self->get_attrib_array(index).set(size, type, norm, stride, self->array_buffer, reinterpret_cast<long>(data));
}
-BufferBindingState *GlState::get_buffer_binding(GLenum target, unsigned index)
+const ArrayState &GlState::get_array(GLenum array) const
{
- if(target==GL_UNIFORM_BUFFER)
- return &uniform_bind_points[index];
- return 0;
+ if(array==GL_VERTEX_ARRAY)
+ return vertex_array;
+ else if(array==GL_NORMAL_ARRAY)
+ return normal_array;
+ else if(array==GL_COLOR_ARRAY)
+ return color_array;
+ else if(array==GL_TEXTURE_COORD_ARRAY)
+ return texcoord_arrays[client_active_tex];
+ else
+ throw logic_error("Invalid array");
}
-void GlState::set_current_texture(GLenum target, unsigned id)
+const ArrayState &GlState::get_texture_coord_array(unsigned index) const
{
- TexUnitState &unit = texunits[active_tex];
- TextureState *tex = 0;
- if(id)
- {
- tex = &textures[id];
- if(!tex->id)
- {
- tex->id = id;
- tex->target = target;
- }
- else if(tex->target!=target)
- return;
- }
- unit.set_current_texture(target, tex);
+ return texcoord_arrays[index];
}
+const ArrayState &GlState::get_attrib_array(unsigned index) const
+{
+ map<unsigned, ArrayState>::const_iterator i = attrib_arrays.find(index);
+ if(i!=attrib_arrays.end())
+ return i->second;
+
+ // XXX Return a dummy?
+ throw runtime_error("Unknown attribute array");
+}
+
+// Array draw commands
+
+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);
+}
+
+// Buffer objects
+
void GlState::set_current_buffer(GLenum target, unsigned id)
{
BufferState *buf = 0;
uniform_buffer = buf;
}
-ArrayState &GlState::get_attrib_array(unsigned index)
+BufferState *GlState::get_buffer_object(unsigned id)
{
- map<unsigned, ArrayState>::iterator i = attrib_arrays.find(index);
- if(i!=attrib_arrays.end())
- return i->second;
-
- ArrayState &array = attrib_arrays[index];
- array.index = index;
+ BufferMap::iterator i = buffers.find(id);
+ return (i==buffers.end() ? 0 : &i->second);
+}
- return array;
+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;
}
-ShaderState *GlState::get_shader(unsigned id, bool create)
+BufferBindingState *GlState::get_buffer_binding(GLenum target, unsigned index)
{
- ShaderMap::iterator i = shaders.find(id);
- if(i==shaders.end() && create)
- {
- i = shaders.insert(ShaderMap::value_type(id, ShaderState())).first;
- i->second.id = id;
- }
- return (i!=shaders.end() ? &i->second : 0);
+ if(target==GL_UNIFORM_BUFFER)
+ return &uniform_bind_points[index];
+ return 0;
}
-void GlState::delete_shader(unsigned id)
+void GlState::glBindBuffer(void *user_data, GLenum target, unsigned id)
{
- ShaderMap::iterator i = shaders.find(id);
- if(i==shaders.end())
- return;
-
- for(ProgramMap::const_iterator j=programs.begin(); j!=programs.end(); ++j)
- {
- const vector<ShaderState *> &prog_shaders = j->second.shaders;
- for(vector<ShaderState *>::const_iterator k=prog_shaders.begin(); k!=prog_shaders.end(); ++k)
- if(*k==&i->second)
- {
- i->second.pending_delete = true;
- return;
- }
- }
-
- shaders.erase(i);
+ reinterpret_cast<GlState *>(user_data)->set_current_buffer(target, id);
}
-void GlState::delete_program(unsigned id)
+void GlState::glBindBufferBase(void *user_data, GLenum target, unsigned index, unsigned id)
{
- ProgramMap::iterator i = programs.find(id);
- if(i==programs.end())
- return;
-
- vector<ShaderState *> prog_shaders = i->second.shaders;
- programs.erase(i);
- for(vector<ShaderState *>::const_iterator j=prog_shaders.begin(); j!=prog_shaders.end(); ++j)
- if((*j)->pending_delete)
- delete_shader((*j)->id);
+ if(BufferState *buffer = reinterpret_cast<GlState *>(user_data)->get_buffer_object(id))
+ glBindBufferRange(user_data, target, index, id, 0, buffer->size);
}
-ProgramState *GlState::get_program(unsigned id, bool create)
+void GlState::glBindBufferRange(void *user_data, GLenum target, unsigned index, unsigned id, int offset, int size)
{
- ProgramMap::iterator i = programs.find(id);
- if(i==programs.end() && create)
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ if(BufferBindingState *binding = self->get_buffer_binding(target, index))
{
- i = programs.insert(ProgramMap::value_type(id, ProgramState())).first;
- i->second.id = id;
+ binding->buffer = self->get_buffer_object(id);
+ binding->offset = offset;
+ binding->size = size;
}
- return (i!=programs.end() ? &i->second : 0);
}
-// Boolean state
-
-void GlState::glEnableClientState(void *user_data, GLenum state)
+void GlState::glBufferData(void *user_data, GLenum target, int size, const void *data, GLenum usage)
{
- reinterpret_cast<GlState *>(user_data)->get_boolean_state(state) = true;
+ if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->get_current_buffer(target))
+ buf->set_data(size, data, usage);
}
-void GlState::glDisableClientState(void *user_data, GLenum state)
+void GlState::glBufferSubData(void *user_data, GLenum target, int offset, int size, const void *data)
{
- reinterpret_cast<GlState *>(user_data)->get_boolean_state(state) = false;
+ if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->get_current_buffer(target))
+ buf->set_sub_data(offset, size, data);
}
-void GlState::glEnableVertexAttribArray(void *user_data, unsigned index)
+void GlState::glDeleteBuffers(void *user_data, int count, const unsigned *ids)
{
- reinterpret_cast<GlState *>(user_data)->attrib_arrays[index].enabled = true;
+ for(int i=0; i<count; ++i)
+ reinterpret_cast<GlState *>(user_data)->buffers.erase(ids[i]);
}
-void GlState::glDisableVertexAttribArray(void *user_data, unsigned index)
+const BufferState &GlState::get_buffer(unsigned id) const
{
- reinterpret_cast<GlState *>(user_data)->attrib_arrays[index].enabled = false;
+ BufferMap::const_iterator i = buffers.find(id);
+ if(i==buffers.end())
+ throw runtime_error("Unknown buffer");
+ return i->second;
}
-// Vertex attributes
-
-void GlState::glColor3f(void *user_data, float r, float g, float b)
-{ glColor4f(user_data, r, g, b, 1.0f); }
-
-void GlState::glColor4f(void *user_data, float r, float g, float b, float a)
+const BufferState *GlState::get_current_buffer(GLenum target) const
{
- Vector4 &color = reinterpret_cast<GlState *>(user_data)->color;
- color.r = r;
- color.g = g;
- color.b = b;
- color.a = a;
+ return const_cast<GlState *>(this)->get_current_buffer(target);
}
-void GlState::glNormal3f(void *user_data, float x, float y, float z)
+const BufferBindingState &GlState::get_buffer_binding(GLenum target, unsigned index) const
{
- Vector3 &normal = reinterpret_cast<GlState *>(user_data)->normal;
- normal.x = x;
- normal.y = y;
- normal.z = z;
+ if(target==GL_UNIFORM_BUFFER)
+ return uniform_bind_points[index];
+ throw runtime_error("This buffer target does not have indexed binding points");
}
-void GlState::glTexCoord1f(void *user_data, float s)
-{ glTexCoord4f(user_data, s, 0.0f, 0.0f, 1.0f); }
-
-void GlState::glTexCoord2f(void *user_data, float s, float t)
-{ glTexCoord4f(user_data, s, t, 0.0f, 1.0f); }
-
-void GlState::glTexCoord3f(void *user_data, float s, float t, float p)
-{ glTexCoord4f(user_data, s, t, p, 1.0f); }
+// Textures
-void GlState::glTexCoord4f(void *user_data, float s, float t, float p, float q)
+void GlState::set_current_texture(GLenum target, unsigned id)
{
- unsigned index = reinterpret_cast<GlState *>(user_data)->active_tex;
- glMultiTexCoord4f(user_data, index, s, t, p, q);
+ TexUnitState &unit = texunits[active_tex];
+ TextureState *tex = 0;
+ if(id)
+ {
+ tex = &textures[id];
+ if(!tex->id)
+ {
+ tex->id = id;
+ tex->target = target;
+ }
+ else if(tex->target!=target)
+ return;
+ }
+ unit.set_current_texture(target, tex);
}
-void GlState::glMultiTexCoord4f(void *user_data, unsigned index, float s, float t, float p, float q)
+TextureState *GlState::get_current_texture(GLenum target)
{
- Vector4 &texcoord = reinterpret_cast<GlState *>(user_data)->texcoord[index];
- texcoord.s = s;
- texcoord.t = t;
- texcoord.p = p;
- texcoord.q = q;
+ return texunits[active_tex].get_current_texture(target);
}
-// Textures
-
void GlState::glActiveTexture(void *user_data, unsigned index)
{
reinterpret_cast<GlState *>(user_data)->active_tex = index-GL_TEXTURE0;
}
void GlState::glTexParameteri(void *user_data, GLenum target, GLenum param, int value)
-{ glTexParameteriv(user_data, target, param, &value); }
+{
+ glTexParameteriv(user_data, target, param, &value);
+}
void GlState::glTexParameteriv(void *user_data, GLenum target, GLenum param, const int *values)
{
reinterpret_cast<GlState *>(user_data)->textures.erase(ids[i]);
}
-// Vertex arrays
-
-void GlState::glVertexPointer(void *user_data, int size, GLenum type, int stride, const void *data)
-{
- GlState *self = reinterpret_cast<GlState *>(user_data);
- self->vertex_array.set(size, type, false, stride, self->array_buffer, reinterpret_cast<long>(data));
-}
-
-void GlState::glNormalPointer(void *user_data, GLenum type, int stride, const void *data)
-{
- GlState *self = reinterpret_cast<GlState *>(user_data);
- self->normal_array.set(3, type, true, stride, self->array_buffer, reinterpret_cast<long>(data));
-}
-
-void GlState::glColorPointer(void *user_data, int size, GLenum type, int stride, const void *data)
-{
- GlState *self = reinterpret_cast<GlState *>(user_data);
- self->color_array.set(size, type, true, stride, self->array_buffer, reinterpret_cast<long>(data));
-}
-
-void GlState::glClientActiveTexture(void *user_data, unsigned index)
+const TextureState &GlState::get_texture(unsigned id) const
{
- reinterpret_cast<GlState *>(user_data)->client_active_tex = index-GL_TEXTURE0;
+ TextureMap::const_iterator i = textures.find(id);
+ if(i==textures.end())
+ throw runtime_error("Unknown texture");
+ return i->second;
}
-void GlState::glTexCoordPointer(void *user_data, int size, GLenum type, int stride, const void *data)
-{
- GlState *self = reinterpret_cast<GlState *>(user_data);
- self->texcoord_arrays[self->client_active_tex].set(size, type, false, stride, self->array_buffer, reinterpret_cast<long>(data));
-}
+// Shaders
-void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, GLenum type, unsigned char norm, int stride, const void *data)
+ShaderState *GlState::get_shader(unsigned id, bool create)
{
- GlState *self = reinterpret_cast<GlState *>(user_data);
- self->get_attrib_array(index).set(size, type, norm, stride, self->array_buffer, reinterpret_cast<long>(data));
+ ShaderMap::iterator i = shaders.find(id);
+ if(i==shaders.end() && create)
+ {
+ i = shaders.insert(ShaderMap::value_type(id, ShaderState())).first;
+ i->second.id = id;
+ }
+ return (i!=shaders.end() ? &i->second : 0);
}
-// Buffer objects
-
-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)
+void GlState::delete_shader(unsigned id)
{
- if(BufferState *buffer = reinterpret_cast<GlState *>(user_data)->get_buffer_object(id))
- glBindBufferRange(user_data, target, index, id, 0, buffer->size);
-}
+ ShaderMap::iterator i = shaders.find(id);
+ if(i==shaders.end())
+ return;
-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))
+ for(ProgramMap::const_iterator j=programs.begin(); j!=programs.end(); ++j)
{
- binding->buffer = self->get_buffer_object(id);
- binding->offset = offset;
- binding->size = size;
+ const vector<ShaderState *> &prog_shaders = j->second.shaders;
+ for(vector<ShaderState *>::const_iterator k=prog_shaders.begin(); k!=prog_shaders.end(); ++k)
+ if(*k==&i->second)
+ {
+ i->second.pending_delete = true;
+ return;
+ }
}
-}
-
-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))
- buf->set_data(size, data, usage);
-}
-void GlState::glBufferSubData(void *user_data, GLenum target, int offset, int size, const void *data)
-{
- if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->get_current_buffer(target))
- buf->set_sub_data(offset, size, data);
+ shaders.erase(i);
}
-void GlState::glDeleteBuffers(void *user_data, int count, const unsigned *ids)
+ProgramState *GlState::get_program(unsigned id, bool create)
{
- for(int i=0; i<count; ++i)
- reinterpret_cast<GlState *>(user_data)->buffers.erase(ids[i]);
+ ProgramMap::iterator i = programs.find(id);
+ if(i==programs.end() && create)
+ {
+ i = programs.insert(ProgramMap::value_type(id, ProgramState())).first;
+ i->second.id = id;
+ }
+ return (i!=programs.end() ? &i->second : 0);
}
-void GlState::glDrawElements(void *user_data, GLenum, int, GLenum type, const void *)
+void GlState::delete_program(unsigned id)
{
- if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->element_buffer)
- buf->content.update_elements(type);
-}
+ ProgramMap::iterator i = programs.find(id);
+ if(i==programs.end())
+ return;
-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);
+ vector<ShaderState *> prog_shaders = i->second.shaders;
+ programs.erase(i);
+ for(vector<ShaderState *>::const_iterator j=prog_shaders.begin(); j!=prog_shaders.end(); ++j)
+ if((*j)->pending_delete)
+ delete_shader((*j)->id);
}
-// Shaders
-
void GlState::glCreateShader(void *user_data, unsigned id, GLenum type)
{
if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, true))
else if(self->programs.count(id))
glGetProgramInfoLog(user_data, id, bufsize, length, log);
}
+
+const ShaderState &GlState::get_shader(unsigned id) const
+{
+ ShaderMap::const_iterator i = shaders.find(id);
+ if(i==shaders.end())
+ throw runtime_error("Unknown shader");
+ return i->second;
+}
+
+const ProgramState &GlState::get_program(unsigned id) const
+{
+ ProgramMap::const_iterator i = programs.find(id);
+ if(i==programs.end())
+ throw runtime_error("Unknown program");
+ return i->second;
+}
~GlState();
int decode(const char *, unsigned);
- const Vector4 &get_color() const { return color; }
- const Vector4 &get_texcoord(unsigned i) const { return texcoord[i]; }
- const Vector3 &get_normal() const { return normal; }
- const TextureMap &get_textures() const { return textures; }
- const TextureState &get_texture(unsigned) const;
- const TexUnitState &get_texture_unit(unsigned i) const { return texunits[i]; }
- 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;
- const ShaderMap &get_shaders() const { return shaders; }
- const ShaderState &get_shader(unsigned) const;
- const ProgramMap &get_programs() const { return programs; }
- const ProgramState &get_program(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);
- ShaderState *get_shader(unsigned, bool);
- void delete_shader(unsigned);
- ProgramState *get_program(unsigned, bool);
- void delete_program(unsigned);
-
static void glEnableClientState(void *, GLenum);
static void glDisableClientState(void *, GLenum);
- static void glEnableVertexAttribArray(void *, unsigned);
- static void glDisableVertexAttribArray(void *, unsigned);
static void glColor3f(void *, float, float, float);
static void glColor4f(void *, float, float, float, float);
static void glTexCoord4f(void *, float, float, float, float);
static void glMultiTexCoord4f(void *, unsigned, float, float, float, float);
- static void glActiveTexture(void *, unsigned);
- static void glBindTexture(void *, GLenum, unsigned);
- static void glTexImage2D(void *, GLenum, int, int, int, int, int, GLenum, GLenum, const void *);
- static void glTexParameteri(void *, GLenum, GLenum, int);
- static void glTexParameteriv(void *, GLenum, GLenum, const int *);
- static void glDeleteTextures(void *, int, const unsigned *);
+public:
+ const Vector4 &get_color() const { return color; }
+ const Vector4 &get_texcoord(unsigned i) const { return texcoord[i]; }
+ const Vector3 &get_normal() const { return normal; }
+
+private:
+ ArrayState &get_attrib_array(unsigned);
static void glVertexPointer(void *, int, GLenum, int, const void *);
static void glNormalPointer(void *, GLenum, int, const void *);
static void glColorPointer(void *, int, GLenum, int, const void *);
static void glClientActiveTexture(void *, unsigned);
static void glTexCoordPointer(void *, int, GLenum, int, const void *);
+ static void glEnableVertexAttribArray(void *, unsigned);
+ static void glDisableVertexAttribArray(void *, unsigned);
static void glVertexAttribPointer(void *, unsigned, int, GLenum, unsigned char, int, const void *);
+public:
+ const ArrayState &get_array(GLenum) const;
+ const ArrayState &get_texture_coord_array(unsigned) const;
+ const ArrayState &get_attrib_array(unsigned) const;
+
+private:
+ static void glDrawElements(void *, GLenum, int, GLenum, const void *);
+ static void glDrawRangeElements(void *, GLenum, unsigned, unsigned, int, GLenum, const void *);
+
+ void set_current_buffer(GLenum, unsigned);
+ BufferState *get_buffer_object(unsigned);
+ BufferState *get_current_buffer(GLenum);
+ BufferBindingState *get_buffer_binding(GLenum, unsigned);
+
static void glBindBuffer(void *, GLenum, unsigned);
static void glBindBufferBase(void *, GLenum, unsigned, unsigned);
static void glBindBufferRange(void *, GLenum, unsigned, unsigned, int, int);
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 *);
+public:
+ 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;
+
+private:
+ void set_current_texture(GLenum, unsigned);
+ TextureState *get_current_texture(GLenum);
+
+ static void glActiveTexture(void *, unsigned);
+ static void glBindTexture(void *, GLenum, unsigned);
+ static void glTexImage2D(void *, GLenum, int, int, int, int, int, GLenum, GLenum, const void *);
+ static void glTexParameteri(void *, GLenum, GLenum, int);
+ static void glTexParameteriv(void *, GLenum, GLenum, const int *);
+ static void glDeleteTextures(void *, int, const unsigned *);
+
+public:
+ const TextureMap &get_textures() const { return textures; }
+ const TextureState &get_texture(unsigned) const;
+ const TexUnitState &get_texture_unit(unsigned i) const { return texunits[i]; }
+
+private:
+ ShaderState *get_shader(unsigned, bool);
+ void delete_shader(unsigned);
+ ProgramState *get_program(unsigned, bool);
+ void delete_program(unsigned);
static void glCreateShader(void *, unsigned, GLenum);
static void glShaderSource(void *, unsigned, int, const char **, const int *);
static void glDeleteObjectARB(void *, unsigned);
static void glGetObjectParameterivARB(void *, unsigned, GLenum, int *);
static void glGetInfoLogARB(void *, unsigned, int, int *, char *);
+
+public:
+ const ShaderMap &get_shaders() const { return shaders; }
+ const ShaderState &get_shader(unsigned) const;
+ const ProgramMap &get_programs() const { return programs; }
+ const ProgramState &get_program(unsigned) const;
};
#endif