+#include <stdexcept>
+#include "misc.h"
+#include "texgen.h"
+#include "texunit.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+TexGen::TexGen():
+ mode(EYE_LINEAR)
+{ }
+
+void TexGen::set_mode(TexGenMode m)
+{
+ mode = m;
+}
+
+void TexGen::set_plane(const Vector4 &p)
+{
+ plane = p;
+}
+
+void TexGen::bind_to(TexCoordComponent c) const
+{
+ if(TexUnit::current().set_texgen(coord_index(c), this))
+ {
+ glTexGeni(c, GL_TEXTURE_GEN_MODE, mode);
+ if(mode==EYE_LINEAR)
+ glTexGenfv(c, GL_EYE_PLANE, &plane.x);
+ else if(mode==OBJECT_LINEAR)
+ glTexGenfv(c, GL_OBJECT_PLANE, &plane.x);
+ enable(GL_TEXTURE_GEN_S+coord_index(c));
+ }
+}
+
+const TexGen *TexGen::current(TexCoordComponent c)
+{
+ return TexUnit::current().get_texgen(coord_index(c));
+}
+
+void TexGen::unbind_from(TexCoordComponent c)
+{
+ if(TexUnit::current().set_texgen(coord_index(c), 0))
+ disable(GL_TEXTURE_GEN_S+coord_index(c));
+}
+
+unsigned TexGen::coord_index(TexCoordComponent c)
+{
+ switch(c)
+ {
+ case SCOORD: return 0;
+ case TCOORD: return 1;
+ case RCOORD: return 2;
+ case QCOORD: return 3;
+ default: throw invalid_argument("TexGen::coord_index");
+ }
+}
+
+} // namespace GL
+} // namespace Msp