0027787: Visualization, TKOpenGl - Optimize rendering by additional check whether...
[occt.git] / src / OpenGl / OpenGl_Clipping.cxx
CommitLineData
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 31OpenGl_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 41void 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 56void OpenGl_Clipping::add (const Handle(OpenGl_Context)& theGlCtx,
79f4f036 57 Graphic3d_SequenceOfHClipPlane& thePlanes)
4269bd1b 58{
79f4f036 59 const bool toUseFfp = theGlCtx->core11 != NULL
60 && theGlCtx->caps->ffpEnable;
61 if (!toUseFfp)
62 {
89a929ea 63 addLazy (theGlCtx, thePlanes);
79f4f036 64 return;
65 }
4269bd1b 66
c827ea3a 67 // Set either identity or pure view matrix.
79f4f036 68 theGlCtx->ApplyWorldViewMatrix();
4269bd1b 69
89a929ea 70 addLazy (theGlCtx, thePlanes);
c827ea3a 71
72 // Restore combined model-view matrix.
79f4f036 73 theGlCtx->ApplyModelViewMatrix();
4269bd1b 74}
75
76// =======================================================================
79f4f036 77// function : addLazy
4269bd1b 78// purpose :
79// =======================================================================
79f4f036 80void OpenGl_Clipping::addLazy (const Handle(OpenGl_Context)& theGlCtx,
79f4f036 81 Graphic3d_SequenceOfHClipPlane& thePlanes)
4269bd1b 82{
79f4f036 83#if !defined(GL_ES_VERSION_2_0)
84 const bool toUseFfp = theGlCtx->core11 != NULL
85 && theGlCtx->caps->ffpEnable;
86#else
87 (void )theGlCtx;
88#endif
89
51b10cd4 90 Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
a9568545 91 while (aPlaneIt.More() && myEmptyPlaneIds->HasFree())
4269bd1b 92 {
93 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
b859a34d 94 if (Contains (aPlane))
95 {
96 thePlanes.Remove (aPlaneIt);
4269bd1b 97 continue;
b859a34d 98 }
4269bd1b 99
b859a34d 100 Standard_Integer anID = myEmptyPlaneIds->Next();
51b10cd4 101 myPlanes.Append (aPlane);
89a929ea 102 myPlaneStates.Bind (aPlane, PlaneProps (anID, Standard_True));
4269bd1b 103
ca3c13d1 104 #if !defined(GL_ES_VERSION_2_0)
79f4f036 105 if (toUseFfp)
106 {
107 ::glEnable ((GLenum)anID);
108 theGlCtx->core11->glClipPlane ((GLenum)anID, aPlane->GetEquation());
109 }
ca3c13d1 110 #endif
3b1817a9 111 if (aPlane->IsCapping())
112 {
113 ++myNbCapping;
114 }
115 else
116 {
117 ++myNbClipping;
118 }
119
b859a34d 120 aPlaneIt.Next();
121 }
4269bd1b 122
a9568545 123 if (!myEmptyPlaneIds->HasFree())
b859a34d 124 {
a9568545 125 while (aPlaneIt.More())
126 {
127 thePlanes.Remove (aPlaneIt);
128 }
4269bd1b 129 }
130}
131
4269bd1b 132// =======================================================================
b859a34d 133// function : Remove
4269bd1b 134// purpose :
135// =======================================================================
79f4f036 136void OpenGl_Clipping::Remove (const Handle(OpenGl_Context)& theGlCtx,
137 const Graphic3d_SequenceOfHClipPlane& thePlanes)
4269bd1b 138{
79f4f036 139#if !defined(GL_ES_VERSION_2_0)
140 const bool toUseFfp = theGlCtx->core11 != NULL
141 && theGlCtx->caps->ffpEnable;
142#else
143 (void )theGlCtx;
144#endif
145
51b10cd4 146 Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
b859a34d 147 for (; aPlaneIt.More(); aPlaneIt.Next())
148 {
149 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
1a7ece8f 150 PlaneProps* aProps = myPlaneStates.ChangeSeek (aPlane);
151 if (aProps == NULL)
b859a34d 152 {
153 continue;
154 }
155
1a7ece8f 156 Standard_Integer anID = aProps->ContextID;
157 if (aProps->IsEnabled)
3b1817a9 158 {
ca3c13d1 159 #if !defined(GL_ES_VERSION_2_0)
79f4f036 160 if (toUseFfp)
161 {
162 ::glDisable ((GLenum)anID);
163 }
ca3c13d1 164 #endif
3b1817a9 165 if (aPlane->IsCapping())
166 {
167 --myNbCapping;
168 }
169 else
170 {
171 --myNbClipping;
172 }
173 }
174
b859a34d 175 myEmptyPlaneIds->Free (anID);
176 myPlaneStates.UnBind (aPlane);
b859a34d 177 }
178
179 // renew collection of planes
180 aPlaneIt.Init (myPlanes);
181 while (aPlaneIt.More())
182 {
183 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
184 if (!myPlaneStates.IsBound (aPlane))
185 {
186 myPlanes.Remove (aPlaneIt);
187 }
188 else
189 {
190 aPlaneIt.Next();
191 }
192 }
4269bd1b 193}
194
195// =======================================================================
196// function : SetEnabled
197// purpose :
198// =======================================================================
79f4f036 199void OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& theGlCtx,
200 const Handle(Graphic3d_ClipPlane)& thePlane,
201 const Standard_Boolean theIsEnabled)
4269bd1b 202{
1a7ece8f 203 PlaneProps* aProps = myPlaneStates.ChangeSeek (thePlane);
204 if (aProps == NULL
205 || aProps->IsEnabled == theIsEnabled)
b859a34d 206 {
4269bd1b 207 return;
b859a34d 208 }
4269bd1b 209
ca3c13d1 210#if !defined(GL_ES_VERSION_2_0)
1a7ece8f 211 GLenum anID = (GLenum)aProps->ContextID;
79f4f036 212 const bool toUseFfp = theGlCtx->core11 != NULL
213 && theGlCtx->caps->ffpEnable;
20aeeb7b 214#else
215 (void )theGlCtx;
ca3c13d1 216#endif
4269bd1b 217 if (theIsEnabled)
b859a34d 218 {
ca3c13d1 219 #if !defined(GL_ES_VERSION_2_0)
79f4f036 220 if (toUseFfp)
221 {
222 ::glEnable (anID);
223 }
ca3c13d1 224 #endif
3b1817a9 225 if (thePlane->IsCapping())
226 {
227 ++myNbCapping;
228 }
229 else
230 {
231 ++myNbClipping;
232 }
b859a34d 233 }
4269bd1b 234 else
b859a34d 235 {
ca3c13d1 236 #if !defined(GL_ES_VERSION_2_0)
79f4f036 237 if (toUseFfp)
238 {
239 ::glDisable (anID);
240 }
ca3c13d1 241 #endif
3b1817a9 242 if (thePlane->IsCapping())
243 {
244 --myNbCapping;
245 }
246 else
247 {
248 --myNbClipping;
249 }
b859a34d 250 }
4269bd1b 251
1a7ece8f 252 aProps->IsEnabled = theIsEnabled;
4269bd1b 253}