4269bd1b |
1 | // Created on: 2013-09-05 |
2 | // Created by: Anton POLETAEV |
d5f74e42 |
3 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
4269bd1b |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
4269bd1b |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
4269bd1b |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
4269bd1b |
15 | |
30f0ad28 |
16 | #include <OpenGl_Clipping.hxx> |
79f4f036 |
17 | |
4269bd1b |
18 | #include <OpenGl_GlCore11.hxx> |
b859a34d |
19 | #include <OpenGl_Workspace.hxx> |
79f4f036 |
20 | #include <OpenGl_Context.hxx> |
4269bd1b |
21 | |
ca3c13d1 |
22 | #if defined(GL_ES_VERSION_2_0) |
23 | // id does not matter for GLSL-based clipping, just for consistency |
24 | #define GL_CLIP_PLANE0 0x3000 |
25 | #endif |
26 | |
4269bd1b |
27 | // ======================================================================= |
28 | // function : OpenGl_ClippingState |
29 | // purpose : |
30 | // ======================================================================= |
30f0ad28 |
31 | OpenGl_Clipping::OpenGl_Clipping () |
ca3c13d1 |
32 | : myEmptyPlaneIds (new Aspect_GenId (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + 5)), |
3b1817a9 |
33 | myNbClipping (0), |
34 | myNbCapping (0) |
4269bd1b |
35 | {} |
36 | |
37 | // ======================================================================= |
38 | // function : Init |
39 | // purpose : |
40 | // ======================================================================= |
30f0ad28 |
41 | void OpenGl_Clipping::Init (const Standard_Integer theMaxPlanes) |
4269bd1b |
42 | { |
43 | myPlanes.Clear(); |
44 | myPlaneStates.Clear(); |
3b1817a9 |
45 | myNbClipping = 0; |
46 | myNbCapping = 0; |
4269bd1b |
47 | Standard_Integer aLowerId = GL_CLIP_PLANE0; |
48 | Standard_Integer aUpperId = GL_CLIP_PLANE0 + theMaxPlanes - 1; |
49 | myEmptyPlaneIds = new Aspect_GenId (aLowerId, aUpperId); |
50 | } |
51 | |
52 | // ======================================================================= |
79f4f036 |
53 | // function : add |
4269bd1b |
54 | // purpose : |
55 | // ======================================================================= |
79f4f036 |
56 | void OpenGl_Clipping::add (const Handle(OpenGl_Context)& theGlCtx, |
57 | const EquationCoords& theCoordSpace, |
58 | Graphic3d_SequenceOfHClipPlane& thePlanes) |
4269bd1b |
59 | { |
79f4f036 |
60 | const bool toUseFfp = theGlCtx->core11 != NULL |
61 | && theGlCtx->caps->ffpEnable; |
62 | if (!toUseFfp) |
63 | { |
64 | addLazy (theGlCtx, theCoordSpace, thePlanes); |
65 | return; |
66 | } |
4269bd1b |
67 | |
c827ea3a |
68 | if (EquationCoords_View == theCoordSpace) |
4269bd1b |
69 | { |
79f4f036 |
70 | theGlCtx->WorldViewState.Push(); |
71 | theGlCtx->WorldViewState.SetIdentity(); |
4269bd1b |
72 | } |
73 | |
c827ea3a |
74 | // Set either identity or pure view matrix. |
79f4f036 |
75 | theGlCtx->ApplyWorldViewMatrix(); |
4269bd1b |
76 | |
79f4f036 |
77 | addLazy (theGlCtx, theCoordSpace, thePlanes); |
4269bd1b |
78 | |
c827ea3a |
79 | if (EquationCoords_View == theCoordSpace) |
4269bd1b |
80 | { |
79f4f036 |
81 | theGlCtx->WorldViewState.Pop(); |
4269bd1b |
82 | } |
c827ea3a |
83 | |
84 | // Restore combined model-view matrix. |
79f4f036 |
85 | theGlCtx->ApplyModelViewMatrix(); |
4269bd1b |
86 | } |
87 | |
88 | // ======================================================================= |
79f4f036 |
89 | // function : addLazy |
4269bd1b |
90 | // purpose : |
91 | // ======================================================================= |
79f4f036 |
92 | void OpenGl_Clipping::addLazy (const Handle(OpenGl_Context)& theGlCtx, |
93 | const EquationCoords& theCoordSpace, |
94 | Graphic3d_SequenceOfHClipPlane& thePlanes) |
4269bd1b |
95 | { |
79f4f036 |
96 | #if !defined(GL_ES_VERSION_2_0) |
97 | const bool toUseFfp = theGlCtx->core11 != NULL |
98 | && theGlCtx->caps->ffpEnable; |
99 | #else |
100 | (void )theGlCtx; |
101 | #endif |
102 | |
51b10cd4 |
103 | Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes); |
a9568545 |
104 | while (aPlaneIt.More() && myEmptyPlaneIds->HasFree()) |
4269bd1b |
105 | { |
106 | const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); |
b859a34d |
107 | if (Contains (aPlane)) |
108 | { |
109 | thePlanes.Remove (aPlaneIt); |
4269bd1b |
110 | continue; |
b859a34d |
111 | } |
4269bd1b |
112 | |
b859a34d |
113 | Standard_Integer anID = myEmptyPlaneIds->Next(); |
51b10cd4 |
114 | myPlanes.Append (aPlane); |
b859a34d |
115 | myPlaneStates.Bind (aPlane, PlaneProps (theCoordSpace, anID, Standard_True)); |
4269bd1b |
116 | |
ca3c13d1 |
117 | #if !defined(GL_ES_VERSION_2_0) |
79f4f036 |
118 | if (toUseFfp) |
119 | { |
120 | ::glEnable ((GLenum)anID); |
121 | theGlCtx->core11->glClipPlane ((GLenum)anID, aPlane->GetEquation()); |
122 | } |
ca3c13d1 |
123 | #endif |
3b1817a9 |
124 | if (aPlane->IsCapping()) |
125 | { |
126 | ++myNbCapping; |
127 | } |
128 | else |
129 | { |
130 | ++myNbClipping; |
131 | } |
132 | |
b859a34d |
133 | aPlaneIt.Next(); |
134 | } |
4269bd1b |
135 | |
a9568545 |
136 | if (!myEmptyPlaneIds->HasFree()) |
b859a34d |
137 | { |
a9568545 |
138 | while (aPlaneIt.More()) |
139 | { |
140 | thePlanes.Remove (aPlaneIt); |
141 | } |
4269bd1b |
142 | } |
143 | } |
144 | |
4269bd1b |
145 | // ======================================================================= |
b859a34d |
146 | // function : Remove |
4269bd1b |
147 | // purpose : |
148 | // ======================================================================= |
79f4f036 |
149 | void OpenGl_Clipping::Remove (const Handle(OpenGl_Context)& theGlCtx, |
150 | const Graphic3d_SequenceOfHClipPlane& thePlanes) |
4269bd1b |
151 | { |
79f4f036 |
152 | #if !defined(GL_ES_VERSION_2_0) |
153 | const bool toUseFfp = theGlCtx->core11 != NULL |
154 | && theGlCtx->caps->ffpEnable; |
155 | #else |
156 | (void )theGlCtx; |
157 | #endif |
158 | |
51b10cd4 |
159 | Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes); |
b859a34d |
160 | for (; aPlaneIt.More(); aPlaneIt.Next()) |
161 | { |
162 | const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); |
163 | if (!Contains (aPlane)) |
164 | { |
165 | continue; |
166 | } |
167 | |
168 | Standard_Integer anID = myPlaneStates.Find (aPlane).ContextID; |
3b1817a9 |
169 | PlaneProps& aProps = myPlaneStates.ChangeFind (aPlane); |
170 | if (aProps.IsEnabled) |
171 | { |
ca3c13d1 |
172 | #if !defined(GL_ES_VERSION_2_0) |
79f4f036 |
173 | if (toUseFfp) |
174 | { |
175 | ::glDisable ((GLenum)anID); |
176 | } |
ca3c13d1 |
177 | #endif |
3b1817a9 |
178 | if (aPlane->IsCapping()) |
179 | { |
180 | --myNbCapping; |
181 | } |
182 | else |
183 | { |
184 | --myNbClipping; |
185 | } |
186 | } |
187 | |
b859a34d |
188 | myEmptyPlaneIds->Free (anID); |
189 | myPlaneStates.UnBind (aPlane); |
b859a34d |
190 | } |
191 | |
192 | // renew collection of planes |
193 | aPlaneIt.Init (myPlanes); |
194 | while (aPlaneIt.More()) |
195 | { |
196 | const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); |
197 | if (!myPlaneStates.IsBound (aPlane)) |
198 | { |
199 | myPlanes.Remove (aPlaneIt); |
200 | } |
201 | else |
202 | { |
203 | aPlaneIt.Next(); |
204 | } |
205 | } |
4269bd1b |
206 | } |
207 | |
208 | // ======================================================================= |
209 | // function : SetEnabled |
210 | // purpose : |
211 | // ======================================================================= |
79f4f036 |
212 | void OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& theGlCtx, |
213 | const Handle(Graphic3d_ClipPlane)& thePlane, |
214 | const Standard_Boolean theIsEnabled) |
4269bd1b |
215 | { |
b859a34d |
216 | if (!Contains (thePlane)) |
217 | { |
4269bd1b |
218 | return; |
b859a34d |
219 | } |
4269bd1b |
220 | |
b859a34d |
221 | PlaneProps& aProps = myPlaneStates.ChangeFind (thePlane); |
222 | if (theIsEnabled == aProps.IsEnabled) |
223 | { |
4269bd1b |
224 | return; |
b859a34d |
225 | } |
4269bd1b |
226 | |
ca3c13d1 |
227 | #if !defined(GL_ES_VERSION_2_0) |
b859a34d |
228 | GLenum anID = (GLenum)aProps.ContextID; |
79f4f036 |
229 | const bool toUseFfp = theGlCtx->core11 != NULL |
230 | && theGlCtx->caps->ffpEnable; |
20aeeb7b |
231 | #else |
232 | (void )theGlCtx; |
ca3c13d1 |
233 | #endif |
4269bd1b |
234 | if (theIsEnabled) |
b859a34d |
235 | { |
ca3c13d1 |
236 | #if !defined(GL_ES_VERSION_2_0) |
79f4f036 |
237 | if (toUseFfp) |
238 | { |
239 | ::glEnable (anID); |
240 | } |
ca3c13d1 |
241 | #endif |
3b1817a9 |
242 | if (thePlane->IsCapping()) |
243 | { |
244 | ++myNbCapping; |
245 | } |
246 | else |
247 | { |
248 | ++myNbClipping; |
249 | } |
b859a34d |
250 | } |
4269bd1b |
251 | else |
b859a34d |
252 | { |
ca3c13d1 |
253 | #if !defined(GL_ES_VERSION_2_0) |
79f4f036 |
254 | if (toUseFfp) |
255 | { |
256 | ::glDisable (anID); |
257 | } |
ca3c13d1 |
258 | #endif |
3b1817a9 |
259 | if (thePlane->IsCapping()) |
260 | { |
261 | --myNbCapping; |
262 | } |
263 | else |
264 | { |
265 | --myNbClipping; |
266 | } |
b859a34d |
267 | } |
4269bd1b |
268 | |
b859a34d |
269 | aProps.IsEnabled = theIsEnabled; |
4269bd1b |
270 | } |