--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#define GL_GLEXT_PROTOTYPES
+#include "program.h"
+#include "shader.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+Program::Program()
+{
+ id=glCreateProgram();
+}
+
+Program::~Program()
+{
+ glDeleteProgram(id);
+}
+
+void Program::attach_shader(Shader &shader)
+{
+ if(find(shaders.begin(), shaders.end(), &shader)==shaders.end())
+ {
+ glAttachShader(id, shader.get_id());
+ shaders.push_back(&shader);
+ }
+}
+
+void Program::detach_shader(Shader &shader)
+{
+ list<Shader *>::iterator i=remove(shaders.begin(), shaders.end(), &shader);
+ if(i!=shaders.end())
+ {
+ shaders.erase(i, shaders.end());
+ glDetachShader(id, shader.get_id());
+ }
+}
+
+bool Program::link()
+{
+ for(list<Shader *>::iterator i=shaders.begin(); i!=shaders.end(); ++i)
+ if(!(*i)->get_compiled() && !(*i)->compile())
+ return false;
+
+ glLinkProgram(id);
+ linked=get_param(GL_LINK_STATUS);
+ return linked;
+}
+
+int Program::get_param(GLenum param) const
+{
+ int value;
+ glGetProgramiv(id, param, &value);
+ return value;
+}
+
+string Program::get_info_log() const
+{
+ sizei len=get_param(GL_INFO_LOG_LENGTH);
+ char log[len+1];
+ glGetProgramInfoLog(id, len+1, reinterpret_cast<GLsizei *>(&len), log);
+ return string(log, len);
+}
+
+} // namespace GL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_PROGRAM_H_
+#define MSP_GL_PROGRAM_H_
+
+#include <list>
+#include <string>
+#include <GL/gl.h>
+#include "shader.h"
+#include "types.h"
+
+namespace Msp {
+namespace GL {
+
+class Shader;
+
+class Program
+{
+public:
+ Program();
+ ~Program();
+
+ void attach_shader(Shader &shader);
+ void detach_shader(Shader &shader);
+ bool link();
+ int get_param(GLenum param) const;
+ std::string get_info_log() const;
+ void bind();
+
+ static void unbind();
+private:
+ uint id;
+ std::list<Shader *> shaders;
+ bool linked;
+
+ static Program *cur_prog;
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#define GL_GLEXT_PROTOTYPES
+#include "shader.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+Shader::Shader(ShaderType t)
+{
+ id=glCreateShader(t);
+}
+
+Shader::~Shader()
+{
+ glDeleteShader(id);
+}
+
+void Shader::source(sizei count, const char **str, const int *len)
+{
+ glShaderSource(id, count, str, len);
+}
+
+void Shader::source(const string &str)
+{
+ source(str.data(), str.size());
+}
+
+void Shader::source(const char *str, int len)
+{
+ source(1, &str, &len);
+}
+
+bool Shader::compile()
+{
+ glCompileShader(id);
+ compiled=get_param(GL_COMPILE_STATUS);
+ return compiled;
+}
+
+int Shader::get_param(GLenum param) const
+{
+ int value;
+ glGetShaderiv(id, param, &value);
+ return value;
+}
+
+string Shader::get_info_log() const
+{
+ sizei len=get_param(GL_INFO_LOG_LENGTH);
+ char log[len+1];
+ glGetShaderInfoLog(id, len+1, reinterpret_cast<GLsizei *>(&len), log);
+ return string(log, len);
+}
+
+} // namespace GL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_SHADER_H_
+#define MSP_GL_SHADER_H_
+
+#include <string>
+#include <GL/gl.h>
+#include "types.h"
+
+namespace Msp {
+namespace GL {
+
+enum ShaderType
+{
+ FRAGMENT_SHADER = GL_FRAGMENT_SHADER,
+ VERTEX_SHADER = GL_VERTEX_SHADER
+};
+
+class Shader
+{
+public:
+ Shader(ShaderType t);
+ ~Shader();
+
+ void source(sizei count, const char **str, const int *len);
+ void source(const std::string &str);
+ void source(const char *str, int len);
+ bool compile();
+ uint get_id() const { return id; }
+ bool get_compiled() const { return compiled; }
+ int get_param(GLenum param) const;
+ std::string get_info_log() const;
+private:
+ uint id;
+ bool compiled;
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "simpleprogram.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+SimpleProgram::SimpleProgram(const string &vert_src, const string &frag_src):
+ vert_shader(VERTEX_SHADER),
+ frag_shader(FRAGMENT_SHADER)
+{
+ vert_shader.source(vert_src);
+ frag_shader.source(frag_src);
+ attach_shader(vert_shader);
+ attach_shader(frag_shader);
+ link();
+}
+
+SimpleProgram::~SimpleProgram()
+{
+ detach_shader(vert_shader);
+ detach_shader(frag_shader);
+}
+
+} // namespace GL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_SIMPLEPROGRAM_H_
+#define MSP_GL_SIMPLEPROGRAM_H_
+
+#include "program.h"
+#include "shader.h"
+
+namespace Msp {
+namespace GL {
+
+class SimpleProgram: public Program
+{
+public:
+ SimpleProgram(const std::string &vert_src, const std::string &frag_src);
+ ~SimpleProgram();
+private:
+ Shader vert_shader;
+ Shader frag_shader;
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif