-#include <msp/gl/extensions/msp_clipping.h>
+#include <msp/core/algorithm.h>
#include "clipping.h"
#include "clipplane.h"
-#include "matrix.h"
-#include "misc.h"
+#include "deviceinfo.h"
+#include "error.h"
using namespace std;
unsigned Clipping::get_n_attach_points()
{
- static Require _req(MSP_clipping);
- static int count = get_i(GL_MAX_CLIP_PLANES);
- return count;
+ return Limits::get_global().max_clip_planes;
}
-void Clipping::attach(unsigned i, const ClipPlane &p)
+void Clipping::attach(const ClipPlane &p)
{
- if(i>=get_n_attach_points())
- throw out_of_range("Clipping::attach");
-
- if(i>=planes.size())
- planes.resize(i+1);
-
- planes[i] = &p;
- if(current()==this)
- glEnable(GL_CLIP_PLANE0+i);
-}
-
-void Clipping::detach(unsigned i)
-{
- if(i>=planes.size())
+ if(find_member(planes, &p, &AttachedPlane::plane)!=planes.end())
return;
+ if(planes.size()>=Limits::get_global().max_clip_planes)
+ throw invalid_operation("Clipping::attach");
- planes[i] = 0;
- if(current()==this)
- disable(GL_CLIP_PLANE0+i);
+ planes.push_back(&p);
}
-void Clipping::update_shader_data(ProgramData &shdata, const Matrix &view_matrix) const
+void Clipping::detach(const ClipPlane &p)
{
- 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);
+ auto i = find_member(planes, &p, &AttachedPlane::plane);
+ if(i!=planes.end())
+ planes.erase(i);
}
-void Clipping::bind() const
+void Clipping::detach(unsigned i)
{
- static Require _req(MSP_clipping);
-
- const Clipping *old = current();
- if(!set_current(this))
- return;
-
- 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);
- }
+ if(i<planes.size())
+ detach(*planes[i].plane);
}
-void Clipping::unbind()
+const ProgramData &Clipping::get_shader_data() const
{
- const Clipping *old = current();
- if(!set_current(0))
- return;
+ for(unsigned i=0; i<planes.size(); ++i)
+ if(planes[i].plane->get_generation()!=planes[i].generation)
+ {
+ planes[i].plane->update_shader_data(shdata, i);
+ planes[i].generation = planes[i].plane->get_generation();
+ }
- for(unsigned i=0; i<old->planes.size(); ++i)
- if(old->planes[i])
- disable(GL_CLIP_PLANE0+i);
+ return shdata;
}
} // namespace GL