+void Program::bind() const
+{
+ if(!linked)
+ throw InvalidState("Program is not linked");
+
+ if(!set_current(this))
+ return;
+
+ glUseProgramObjectARB(id);
+}
+
+int Program::get_uniform_location(const string &n) const
+{
+ return glGetUniformLocationARB(id, n.c_str());
+}
+
+void Program::unbind()
+{
+ if(!set_current(0))
+ return;
+
+ glUseProgramObjectARB(0);
+}
+
+
+Program::Loader::Loader(Program &p):
+ DataFile::ObjectLoader<Program>(p)
+{
+ obj.set_del_shaders(true);
+
+ add("vertex_shader", &Loader::vertex_shader);
+ add("fragment_shader", &Loader::fragment_shader);
+ add("attribute", &Loader::attribute);
+}
+
+void Program::Loader::vertex_shader(const string &src)
+{
+ obj.attach_shader(*new Shader(VERTEX_SHADER, src));
+}
+
+void Program::Loader::fragment_shader(const string &src)
+{
+ obj.attach_shader(*new Shader(FRAGMENT_SHADER, src));
+}
+
+void Program::Loader::attribute(unsigned i, const string &n)
+{
+ obj.bind_attribute(i, n);
+}
+
+void Program::Loader::finish()
+{
+ obj.link();
+}
+