--- /dev/null
+#include <msp/gl/extensions/msp_legacy_features.h>
+#include "clipping.h"
+#include "clipplane.h"
+#include "clipunit.h"
+#include "matrix.h"
+#include "misc.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+bool Clipping::bound_with_legacy = false;
+
+void Clipping::attach(unsigned i, const ClipPlane &p)
+{
+ if(i>=ClipUnit::get_n_units())
+ throw out_of_range("Clipping::attach");
+
+ if(i>=planes.size())
+ planes.resize(i+1);
+
+ planes[i] = &p;
+ if(current()==this)
+ {
+ if(bound_with_legacy)
+ p.bind_to(i);
+ else
+ glEnable(GL_CLIP_PLANE0+i);
+ }
+}
+
+void Clipping::detach(unsigned i)
+{
+ if(i>=planes.size())
+ return;
+
+ planes[i] = 0;
+ if(current()==this)
+ {
+ if(bound_with_legacy)
+ ClipPlane::unbind_from(i);
+ else
+ disable(GL_CLIP_PLANE0+i);
+ }
+}
+
+void Clipping::update_shader_data(ProgramData &shdata, const Matrix &view_matrix) const
+{
+ Matrix view_inverse = invert(view_matrix);
+ for(unsigned i=0; i<planes.size(); ++i)
+ if(planes[i])
+ planes[i]->update_shader_data(shdata, view_inverse, i);
+}
+
+void Clipping::bind(bool legacy) const
+{
+ if(legacy)
+ static Require _req(MSP_legacy_features);
+
+ const Clipping *old = current();
+ if(!set_current(this))
+ return;
+
+ bound_with_legacy = legacy;
+ if(legacy)
+ {
+ for(unsigned i=0; i<planes.size(); ++i)
+ {
+ if(planes[i])
+ planes[i]->bind_to(i);
+ else
+ ClipPlane::unbind_from(i);
+ }
+
+ if(old)
+ {
+ for(unsigned i=planes.size(); i<old->planes.size(); ++i)
+ ClipPlane::unbind_from(i);
+ }
+ }
+ else
+ {
+ for(unsigned i=0; i<planes.size(); ++i)
+ {
+ if(planes[i])
+ enable(GL_CLIP_PLANE0+i);
+ else
+ disable(GL_CLIP_PLANE0+i);
+ }
+
+ if(old)
+ {
+ for(unsigned i=planes.size(); i<old->planes.size(); ++i)
+ disable(GL_CLIP_PLANE0+i);
+ }
+ }
+}
+
+void Clipping::unbind()
+{
+}
+
+} // namespace GL
+} // namespace Msp