0024070: OpenGL capped object-level clipping planes
[occt.git] / src / OpenGl / OpenGl_ClippingState.cxx
1 // Created on: 2013-09-05
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2013 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 #include <OpenGl_ClippingState.hxx>
21 #include <OpenGl_GlCore11.hxx>
22
23 namespace
24 {
25   static const GLdouble OpenGl_DefaultPlaneEq[] = {0.0, 0.0, 0.0, 0.0};
26 };
27
28 // =======================================================================
29 // function : OpenGl_ClippingState
30 // purpose  :
31 // =======================================================================
32 OpenGl_ClippingState::OpenGl_ClippingState ()
33 : myPlanes(),
34   myPlaneStates(),
35   myEmptyPlaneIds (new Aspect_GenId (GL_CLIP_PLANE0, GL_CLIP_PLANE5))
36 {}
37
38 // =======================================================================
39 // function : Init
40 // purpose  :
41 // =======================================================================
42 void OpenGl_ClippingState::Init (const Standard_Integer theMaxPlanes)
43 {
44   myPlanes.Clear();
45   myPlaneStates.Clear();
46   Standard_Integer aLowerId = GL_CLIP_PLANE0;
47   Standard_Integer aUpperId = GL_CLIP_PLANE0 + theMaxPlanes - 1;
48   myEmptyPlaneIds = new Aspect_GenId (aLowerId, aUpperId);
49 }
50
51 // =======================================================================
52 // function : Planes
53 // purpose  :
54 // =======================================================================
55 Graphic3d_SetOfHClipPlane OpenGl_ClippingState::Planes() const
56 {
57   Graphic3d_SetOfHClipPlane aRes;
58   OpenGl_MapOfContextPlanes::Iterator anIt (myPlanes);
59   for (; anIt.More(); anIt.Next())
60   {
61     aRes.Add (anIt.Key());
62   }
63
64   return aRes;
65 }
66
67 // =======================================================================
68 // function : IsSet
69 // purpose  :
70 // =======================================================================
71 Standard_Boolean OpenGl_ClippingState::IsSet (const Handle(Graphic3d_ClipPlane)& thePlane) const
72 {
73   return myPlanes.IsBound (thePlane);
74 }
75
76 // =======================================================================
77 // function : Set
78 // purpose  :
79 // =======================================================================
80 void OpenGl_ClippingState::Set (const Graphic3d_SetOfHClipPlane& thePlanes,
81                                 const Standard_Boolean theToEnable)
82 {
83   Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
84   for (; aPlaneIt.More() && myEmptyPlaneIds->Available() > 0; aPlaneIt.Next())
85   {
86     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
87     if (IsSet (aPlane))
88       return;
89
90     Standard_Integer anId = myEmptyPlaneIds->Next();
91     myPlanes.Bind (aPlane, anId);
92     myPlaneStates.Bind (aPlane, theToEnable);
93
94     const GLenum anOpenGlId = (GLenum)anId;
95     if (theToEnable)
96     {
97       glEnable (anOpenGlId);
98     }
99     else
100     {
101       glDisable (anOpenGlId);
102     }
103
104     glClipPlane (anOpenGlId, aPlane->GetEquation());
105   }
106 }
107
108 // =======================================================================
109 // function : Set
110 // purpose  :
111 // =======================================================================
112 void OpenGl_ClippingState::Set (const Graphic3d_SetOfHClipPlane& thePlanes,
113                                 const OpenGl_Matrix* theViewMatrix,
114                                 const Standard_Boolean theToEnable)
115 {
116   GLint aMatrixMode;
117   glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
118
119   OpenGl_Matrix aCurrentMat;
120   glGetFloatv (GL_MODELVIEW_MATRIX, (GLfloat*)aCurrentMat.mat);
121
122   if (aMatrixMode != GL_MODELVIEW)
123   {
124     glMatrixMode (GL_MODELVIEW);
125   }
126
127   // load equation transform matrices
128   glLoadMatrixf ((theViewMatrix != NULL)
129     ? (const GLfloat*)theViewMatrix->mat
130     : (const GLfloat*)OpenGl_IdentityMatrix.mat);
131
132   Set (thePlanes, theToEnable);
133
134   // restore model-view matrix
135   glLoadMatrixf ((GLfloat*)aCurrentMat.mat);
136
137   // restore context matrix state
138   if (aMatrixMode != GL_MODELVIEW)
139   {
140     glMatrixMode (aMatrixMode);
141   }
142 }
143
144 // =======================================================================
145 // function : Unset
146 // purpose  :
147 // =======================================================================
148 void OpenGl_ClippingState::Unset (const Graphic3d_SetOfHClipPlane& thePlanes)
149 {
150   Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
151   for (; aPlaneIt.More(); aPlaneIt.Next())
152   {
153     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
154     if (!IsSet (aPlane))
155       continue;
156
157     Standard_Integer anId = myPlanes.Find (aPlane);
158     myEmptyPlaneIds->Free (anId);
159     myPlanes.UnBind (aPlane);
160     myPlaneStates.UnBind (aPlane);
161
162     const GLenum anOpenGlId = (GLenum)anId;
163
164     glDisable (anOpenGlId);
165     glClipPlane (anOpenGlId, OpenGl_DefaultPlaneEq);
166   }
167 }
168
169 //
170 //// =======================================================================
171 //// function : SetPlane
172 //// purpose  :
173 //// =======================================================================
174 //Standard_Boolean OpenGl_ClippingState::SetPlane (const Handle(Graphic3d_ClipPlane)& thePlane,
175 //                                                 const Standard_Boolean theToEnable)
176 //{
177 //  if (myEmptyPlaneIds->Available() == 0)
178 //    return Standard_False;
179 //
180 //  if (IsPlaneSet (thePlane))
181 //    return Standard_True;
182 //
183 //  Standard_Integer aPlaneId = myEmptyPlaneIds->Next();
184 //  myPlanes.Bind (thePlane, aPlaneId);
185 //  myPlaneStates.Bind (thePlane, theToEnable);
186 //  if (theToEnable)
187 //    glEnable (aPlaneId);
188 //  else
189 //    glDisable (aPlaneId);
190 //
191 //  glClipPlane (aPlaneId, thePlane->GetEquation());
192 //
193 //  return Standard_True;
194 //}
195
196 //// =======================================================================
197 //// function : UnsetPlane
198 //// purpose  :
199 //// =======================================================================
200 //void OpenGl_ClippingState::UnsetPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
201 //{
202 //  if (!IsPlaneSet (thePlane))
203 //    return;
204 //
205 //  Standard_Integer aPlaneId = myPlanes.Find (thePlane);
206 //
207 //  myEmptyPlaneIds->Free (aPlaneId);
208 //  myPlanes.UnBind (thePlane);
209 //  myPlaneStates.UnBind (thePlane);
210 //
211 //  glDisable (aPlaneId);
212 //  glClipPlane (aPlaneId, OpenGl_DefaultPlaneEq);
213 //}
214
215 // =======================================================================
216 // function : IsEnabled
217 // purpose  :
218 // =======================================================================
219 Standard_Boolean OpenGl_ClippingState::IsEnabled (const Handle(Graphic3d_ClipPlane)& thePlane) const
220 {
221   Standard_Boolean isSet;
222   return IsSet (thePlane)
223       && myPlaneStates.Find (thePlane, isSet)
224       && isSet;
225 }
226
227 // =======================================================================
228 // function : SetEnabled
229 // purpose  :
230 // =======================================================================
231 void OpenGl_ClippingState::SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane,
232                                        const Standard_Boolean theIsEnabled)
233 {
234   if (!IsSet (thePlane))
235     return;
236
237   Standard_Boolean& aState = myPlaneStates.ChangeFind (thePlane);
238   if (theIsEnabled == aState)
239     return;
240
241   Standard_Integer aPlaneId = myPlanes.Find (thePlane);
242   if (theIsEnabled)
243     glEnable (aPlaneId);
244   else
245     glDisable (aPlaneId);
246
247   aState = theIsEnabled;
248 }