]> git.tdb.fi Git - libs/gl.git/blob - source/clipping.cpp
Add a utility class for switching renderables
[libs/gl.git] / source / clipping.cpp
1 #include <msp/gl/extensions/msp_clipping.h>
2 #include <msp/gl/extensions/msp_legacy_features.h>
3 #include "clipping.h"
4 #include "clipplane.h"
5 #include "clipunit.h"
6 #include "matrix.h"
7 #include "misc.h"
8
9 using namespace std;
10
11 namespace Msp {
12 namespace GL {
13
14 bool Clipping::bound_with_legacy = false;
15
16 void Clipping::attach(unsigned i, const ClipPlane &p)
17 {
18         if(i>=ClipUnit::get_n_units())
19                 throw out_of_range("Clipping::attach");
20
21         if(i>=planes.size())
22                 planes.resize(i+1);
23
24         planes[i] = &p;
25         if(current()==this)
26         {
27                 if(bound_with_legacy)
28                         p.bind_to(i);
29                 else
30                         glEnable(GL_CLIP_PLANE0+i);
31         }
32 }
33
34 void Clipping::detach(unsigned i)
35 {
36         if(i>=planes.size())
37                 return;
38
39         planes[i] = 0;
40         if(current()==this)
41         {
42                 if(bound_with_legacy)
43                         ClipPlane::unbind_from(i);
44                 else
45                         disable(GL_CLIP_PLANE0+i);
46         }
47 }
48
49 void Clipping::update_shader_data(ProgramData &shdata, const Matrix &view_matrix) const
50 {
51         Matrix view_inverse = invert(view_matrix);
52         for(unsigned i=0; i<planes.size(); ++i)
53                 if(planes[i])
54                         planes[i]->update_shader_data(shdata, view_inverse, i);
55 }
56
57 void Clipping::bind(bool legacy) const
58 {
59         static Require _req(MSP_clipping);
60         if(legacy)
61                 static Require _req2(MSP_legacy_features);
62         
63         if(legacy!=bound_with_legacy)
64                 unbind();
65
66         const Clipping *old = current();
67         if(!set_current(this))
68                 return;
69
70         bound_with_legacy = legacy;
71         if(legacy)
72         {
73                 for(unsigned i=0; i<planes.size(); ++i)
74                 {
75                         if(planes[i])
76                                 planes[i]->bind_to(i);
77                         else
78                                 ClipPlane::unbind_from(i);
79                 }
80
81                 if(old)
82                 {
83                         for(unsigned i=planes.size(); i<old->planes.size(); ++i)
84                                 ClipPlane::unbind_from(i);
85                 }
86         }
87         else
88         {
89                 for(unsigned i=0; i<planes.size(); ++i)
90                 {
91                         if(planes[i])
92                                 enable(GL_CLIP_PLANE0+i);
93                         else
94                                 disable(GL_CLIP_PLANE0+i);
95                 }
96
97                 if(old)
98                 {
99                         for(unsigned i=planes.size(); i<old->planes.size(); ++i)
100                                 disable(GL_CLIP_PLANE0+i);
101                 }
102         }
103 }
104
105 void Clipping::unbind()
106 {
107         const Clipping *old = current();
108         if(!set_current(0))
109                 return;
110
111         if(bound_with_legacy)
112         {
113                 for(unsigned i=0; i<old->planes.size(); ++i)
114                         if(old->planes[i])
115                                 ClipPlane::unbind_from(i);
116         }
117         else
118         {
119                 for(unsigned i=0; i<old->planes.size(); ++i)
120                         if(old->planes[i])
121                                 disable(GL_CLIP_PLANE0+i);
122         }
123 }
124
125 } // namespace GL
126 } // namespace Msp