0025258: Uninitialized class field in IntPatch_CSFunction
[occt.git] / src / OpenGl / OpenGl_CappingAlgo.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
16#include <OpenGl_CappingAlgo.hxx>
17#include <OpenGl_Workspace.hxx>
18#include <OpenGl_Context.hxx>
19#include <OpenGl_PrimitiveArray.hxx>
20#include <OpenGl_CappingPlaneResource.hxx>
21#include <OpenGl_Vec.hxx>
b64d84be 22#include <OpenGl_Structure.hxx>
4269bd1b 23
24IMPLEMENT_STANDARD_HANDLE(OpenGl_CappingAlgoFilter, OpenGl_RenderFilter)
25IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingAlgoFilter, OpenGl_RenderFilter)
26
27Handle(OpenGl_RenderFilter) OpenGl_CappingAlgo::myRenderFilter;
28OpenGl_AspectFace OpenGl_CappingAlgo::myFrontCulling;
29OpenGl_AspectFace OpenGl_CappingAlgo::myNoneCulling;
30Standard_Boolean OpenGl_CappingAlgo::myIsInit = Standard_False;
31
32namespace
33{
34 static const OpenGl_Vec4 THE_CAPPING_PLN_VERTS[12] =
35 { OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
36 OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f),
37 OpenGl_Vec4 ( 0.0f, 0.0f, 1.0f, 0.0f),
38 OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
39 OpenGl_Vec4 ( 0.0f, 0.0f, 1.0f, 0.0f),
40 OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
41 OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
42 OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
43 OpenGl_Vec4 ( 0.0f, 0.0f,-1.0f, 0.0f),
44 OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
45 OpenGl_Vec4 ( 0.0f, 0.0f,-1.0f, 0.0f),
46 OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f) };
47
48 static const OpenGl_Vec4 THE_CAPPING_PLN_TCOORD[12] =
49 { OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
50 OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f),
51 OpenGl_Vec4 ( 0.0f, 1.0f, 0.0f, 0.0f),
52 OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
53 OpenGl_Vec4 ( 0.0f, 1.0f, 0.0f, 0.0f),
54 OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
55 OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
56 OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
57 OpenGl_Vec4 ( 0.0f,-1.0f, 0.0f, 0.0f),
58 OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
59 OpenGl_Vec4 ( 0.0f,-1.0f, 0.0f, 0.0f),
60 OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f) };
61};
62
63// =======================================================================
64// function : RenderCapping
65// purpose :
66// =======================================================================
b64d84be 67void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace,
68 const Graphic3d_SequenceOfGroup& theGroups)
4269bd1b 69{
4269bd1b 70 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
71
b859a34d 72 // check whether algorithm need to be performed
4269bd1b 73 Standard_Boolean isCapping = Standard_False;
51b10cd4 74 const Graphic3d_SequenceOfHClipPlane& aContextPlanes = aContext->Clipping().Planes();
75 Graphic3d_SequenceOfHClipPlane::Iterator aCappingIt (aContextPlanes);
4269bd1b 76 for (; aCappingIt.More(); aCappingIt.Next())
77 {
78 const Handle(Graphic3d_ClipPlane)& aPlane = aCappingIt.Value();
79 if (aPlane->IsCapping())
80 {
81 isCapping = Standard_True;
82 break;
83 }
84 }
85
86 // do not perform algorithm is there is nothing to render
87 if (!isCapping)
b859a34d 88 {
4269bd1b 89 return;
b859a34d 90 }
4269bd1b 91
92 // init internal data
93 Init();
94
95 // remember current aspect face defined in workspace
96 const OpenGl_AspectFace* aFaceAsp = theWorkspace->AspectFace (Standard_False);
97
98 // replace primitive groups rendering filter
99 static Handle(OpenGl_CappingAlgoFilter) aCappingFilter = new OpenGl_CappingAlgoFilter();
100 Handle(OpenGl_RenderFilter) aRenderFilter = theWorkspace->GetRenderFilter();
101 theWorkspace->SetRenderFilter (aCappingFilter);
102
103 // prepare for rendering the clip planes
104 glEnable (GL_STENCIL_TEST);
105
347423b2 106 // remember current state of depth
107 // function and change its value
108 GLint aDepthFuncPrev;
109 glGetIntegerv (GL_DEPTH_FUNC, &aDepthFuncPrev);
110 glDepthFunc (GL_LESS);
111
4269bd1b 112 // generate capping for every clip plane
113 for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next())
114 {
115 // get plane being rendered
116 const Handle(Graphic3d_ClipPlane)& aRenderPlane = aCappingIt.Value();
117 if (!aRenderPlane->IsCapping())
118 {
119 continue;
120 }
121
122 // enable only the rendering plane to generate stencil mask
51b10cd4 123 Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aContextPlanes);
4269bd1b 124 for (; aPlaneIt.More(); aPlaneIt.Next())
125 {
126 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
127 const Standard_Boolean isOn = (aPlane == aRenderPlane);
128 aContext->ChangeClipping().SetEnabled (aPlane, isOn);
129 }
130
131 glClear (GL_STENCIL_BUFFER_BIT);
132 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
133
134 // override aspects, disable culling
135 theWorkspace->SetAspectFace (NoneCulling());
136 theWorkspace->AspectFace (Standard_True);
137
138 // evaluate number of pair faces
139 glDisable (GL_DEPTH_TEST);
140 glDepthMask (GL_FALSE);
141 glStencilFunc (GL_ALWAYS, 1, 0x01);
142 glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT);
143
b64d84be 144 for (OpenGl_Structure::GroupIterator aGroupIt (theGroups); aGroupIt.More(); aGroupIt.Next())
4269bd1b 145 {
31c0e219 146 if (aGroupIt.Value()->IsClosed())
147 {
148 aGroupIt.Value()->Render (theWorkspace);
149 }
4269bd1b 150 }
151
b859a34d 152 // override material, cull back faces
4269bd1b 153 theWorkspace->SetAspectFace (FrontCulling());
154 theWorkspace->AspectFace (Standard_True);
155
156 // enable all clip plane except the rendered one
157 for (aPlaneIt.Init (aContextPlanes); aPlaneIt.More(); aPlaneIt.Next())
158 {
159 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
160 const Standard_Boolean isOn = (aPlane != aRenderPlane);
161 aContext->ChangeClipping().SetEnabled (aPlane, isOn);
162 }
163
164 // render capping plane using the generated stencil mask
165 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
166 glDepthMask (GL_TRUE);
4269bd1b 167 glStencilFunc (GL_EQUAL, 1, 0x01);
168 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
169 glEnable (GL_DEPTH_TEST);
170
171 RenderPlane (theWorkspace, aRenderPlane);
172 }
173
174 // restore previous application state
175 glClear (GL_STENCIL_BUFFER_BIT);
347423b2 176 glDepthFunc (aDepthFuncPrev);
4269bd1b 177 glStencilFunc (GL_ALWAYS, 0, 0xFF);
178 glDisable (GL_STENCIL_TEST);
179
180 // enable clipping
181 for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next())
182 {
183 aContext->ChangeClipping().SetEnabled (aCappingIt.Value(), Standard_True);
184 }
185
186 // restore rendering aspects
187 theWorkspace->SetAspectFace (aFaceAsp);
188 theWorkspace->SetRenderFilter (aRenderFilter);
189}
190
191// =======================================================================
192// function : RenderPlane
193// purpose :
194// =======================================================================
195void OpenGl_CappingAlgo::RenderPlane (const Handle(OpenGl_Workspace)& theWorkspace,
196 const Handle(Graphic3d_ClipPlane)& thePlane)
197{
198 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
199
200 // get resource for the plane
201 TCollection_AsciiString aResId = thePlane->GetId();
202
203 Handle(OpenGl_CappingPlaneResource) aPlaneRes;
204 if (!aContext->GetResource (aResId, aPlaneRes))
205 {
206 // share and register for release once the resource is no longer used
207 aPlaneRes = new OpenGl_CappingPlaneResource (thePlane);
208 aContext->ShareResource (aResId, aPlaneRes);
209 }
210
211 aPlaneRes->Update (aContext);
212
213 const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace (Standard_False);
214 const OpenGl_AspectFace* aPlaneAspect = aPlaneRes->AspectFace();
215 if (aPlaneAspect != NULL)
216 {
217 theWorkspace->SetAspectFace (aPlaneAspect);
218 }
219
220 // apply aspect for rendering
221 theWorkspace->AspectFace (Standard_True);
222
223 // set identity model matrix
224 const OpenGl_Matrix* aModelMatrix = theWorkspace->SetStructureMatrix (&OpenGl_IdentityMatrix);
225
226 glMultMatrixf ((const GLfloat*)aPlaneRes->Orientation());
227 glNormal3f (0.0f, 1.0f, 0.0f);
228 glEnableClientState (GL_VERTEX_ARRAY);
229 glVertexPointer (4, GL_FLOAT, 0, (GLfloat* )&THE_CAPPING_PLN_VERTS);
230 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
231 glTexCoordPointer (4, GL_FLOAT, 0, (GLfloat*)&THE_CAPPING_PLN_TCOORD);
232 glDrawArrays (GL_TRIANGLES, 0, 12);
233 glDisableClientState (GL_VERTEX_ARRAY);
234 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
235
392ac980 236 theWorkspace->SetStructureMatrix (aModelMatrix, true);
4269bd1b 237 theWorkspace->SetAspectFace (aFaceAspect);
238
239 // set delayed resource release
240 aPlaneRes.Nullify();
241 aContext->ReleaseResource (aResId, Standard_True);
242}
243
244// =======================================================================
245// function : Init
246// purpose :
247// =======================================================================
248void OpenGl_CappingAlgo::Init()
249{
250 if (myIsInit)
251 return;
252
253 myRenderFilter = new OpenGl_CappingAlgoFilter();
fd4a6963 254 myNoneCulling.ChangeCullingMode() = TelCullNone;
255 myNoneCulling.ChangeEdge() = 0;
4269bd1b 256
fd4a6963 257 myFrontCulling.ChangeCullingMode() = TelCullBack;
258 myFrontCulling.ChangeEdge() = 0;
4269bd1b 259
260 myIsInit = Standard_True;
261}
262
263// =======================================================================
264// function : CanRender
265// purpose :
266// =======================================================================
267Standard_Boolean OpenGl_CappingAlgoFilter::CanRender (const OpenGl_Element* theElement)
268{
871fa103 269 const OpenGl_PrimitiveArray* aPArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
270 return aPArray != NULL
271 && aPArray->DrawMode() >= GL_TRIANGLES
272 && aPArray->DrawMode() <= GL_POLYGON;
4269bd1b 273}