+
+// Shaders
+
+void GlState::glCreateShader(void *user_data, unsigned id, GLenum type)
+{
+ if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, true))
+ shader->type = type;
+}
+
+void GlState::glShaderSource(void *user_data, unsigned id, int count, const char **str, const int *length)
+{
+ if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, false))
+ {
+ shader->source.clear();
+ for(int i=0; i<count; ++i)
+ {
+ if(!length || length[i]<0)
+ shader->source.push_back(str[i]);
+ else
+ shader->source.push_back(string(str[i], length[i]));
+ }
+ shader->source_changed = true;
+ }
+}
+
+void GlState::glCompileShader(void *user_data, unsigned id)
+{
+ if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, false))
+ shader->source_changed = false;
+}
+
+void GlState::glGetShaderiv(void *user_data, unsigned id, GLenum pname, int *param)
+{
+ if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, false))
+ {
+ if(pname==GL_COMPILE_STATUS)
+ shader->compile_status = *param;
+ }
+}
+
+void GlState::glGetShaderInfoLog(void *user_data, unsigned id, int, int *, char *log)
+{
+ if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, false))
+ shader->info_log = log;
+}
+
+void GlState::glDeleteShader(void *user_data, unsigned id)
+{
+ reinterpret_cast<GlState *>(user_data)->delete_shader(id);
+}
+
+void GlState::glCreateProgram(void *user_data, unsigned id)
+{
+ reinterpret_cast<GlState *>(user_data)->get_program(id, true);
+}
+
+void GlState::glAttachShader(void *user_data, unsigned prog_id, unsigned shader_id)
+{
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ if(ProgramState *prog = self->get_program(prog_id, false))
+ if(ShaderState *shader = self->get_shader(shader_id, false))
+ prog->shaders.push_back(shader);
+}
+
+void GlState::glLinkProgram(void *user_data, unsigned id)
+{
+ if(ProgramState *program = reinterpret_cast<GlState *>(user_data)->get_program(id, false))
+ program->shaders_changed = false;
+}
+
+void GlState::glGetProgramiv(void *user_data, unsigned id, GLenum pname, int *param)
+{
+ if(ProgramState *program = reinterpret_cast<GlState *>(user_data)->get_program(id, false))
+ {
+ if(pname==GL_LINK_STATUS)
+ program->link_status = *param;
+ }
+}
+
+void GlState::glGetProgramInfoLog(void *user_data, unsigned id, int, int *, char *log)
+{
+ if(ProgramState *program = reinterpret_cast<GlState *>(user_data)->get_program(id, false))
+ program->info_log = log;
+}
+
+void GlState::glDeleteProgram(void *user_data, unsigned id)
+{
+ reinterpret_cast<GlState *>(user_data)->delete_program(id);
+}
+
+void GlState::glDeleteObjectARB(void *user_data, unsigned id)
+{
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ if(self->shaders.count(id))
+ self->delete_shader(id);
+ else if(self->programs.count(id))
+ self->delete_program(id);
+}
+
+void GlState::glGetObjectParameterivARB(void *user_data, unsigned id, GLenum pname, int *param)
+{
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ if(self->shaders.count(id))
+ glGetShaderiv(user_data, id, pname, param);
+ else if(self->programs.count(id))
+ glGetProgramiv(user_data, id, pname, param);
+}
+
+void GlState::glGetInfoLogARB(void *user_data, unsigned id, int bufsize, int *length, char *log)
+{
+ GlState *self = reinterpret_cast<GlState *>(user_data);
+ if(self->shaders.count(id))
+ glGetShaderInfoLog(user_data, id, bufsize, length, log);
+ else if(self->programs.count(id))
+ glGetProgramInfoLog(user_data, id, bufsize, length, log);
+}