0027750: Visualization, V3d_View - remove unused functionality ZClipping and ZCueing
[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>
deb02f86 17
4269bd1b 18#include <OpenGl_Workspace.hxx>
19#include <OpenGl_Context.hxx>
20#include <OpenGl_PrimitiveArray.hxx>
21#include <OpenGl_CappingPlaneResource.hxx>
22#include <OpenGl_Vec.hxx>
b64d84be 23#include <OpenGl_Structure.hxx>
deb02f86 24#include <OpenGl_ShaderManager.hxx>
4269bd1b 25
92efcf78 26IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingAlgoFilter,OpenGl_RenderFilter)
27
4269bd1b 28namespace
29{
ca3c13d1 30#if !defined(GL_ES_VERSION_2_0)
31 static const GLint THE_FILLPRIM_FROM = GL_TRIANGLES;
32 static const GLint THE_FILLPRIM_TO = GL_POLYGON;
33#else
34 static const GLint THE_FILLPRIM_FROM = GL_TRIANGLES;
35 static const GLint THE_FILLPRIM_TO = GL_TRIANGLE_FAN;
36#endif
ca3c13d1 37}
4269bd1b 38
39// =======================================================================
40// function : RenderCapping
41// purpose :
42// =======================================================================
cc6852f3 43void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace,
44 const OpenGl_Structure& theStructure)
4269bd1b 45{
4269bd1b 46 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
47
b859a34d 48 // check whether algorithm need to be performed
4269bd1b 49 Standard_Boolean isCapping = Standard_False;
51b10cd4 50 const Graphic3d_SequenceOfHClipPlane& aContextPlanes = aContext->Clipping().Planes();
51 Graphic3d_SequenceOfHClipPlane::Iterator aCappingIt (aContextPlanes);
4269bd1b 52 for (; aCappingIt.More(); aCappingIt.Next())
53 {
54 const Handle(Graphic3d_ClipPlane)& aPlane = aCappingIt.Value();
55 if (aPlane->IsCapping())
56 {
57 isCapping = Standard_True;
58 break;
59 }
60 }
61
62 // do not perform algorithm is there is nothing to render
63 if (!isCapping)
b859a34d 64 {
4269bd1b 65 return;
b859a34d 66 }
4269bd1b 67
4269bd1b 68 // remember current aspect face defined in workspace
f9ba5c4d 69 const OpenGl_AspectFace* aFaceAsp = theWorkspace->AspectFace();
4269bd1b 70
71 // replace primitive groups rendering filter
4269bd1b 72 Handle(OpenGl_RenderFilter) aRenderFilter = theWorkspace->GetRenderFilter();
f8ae3605 73 theWorkspace->SetRenderFilter (theWorkspace->DefaultCappingAlgoFilter());
4269bd1b 74
75 // prepare for rendering the clip planes
76 glEnable (GL_STENCIL_TEST);
77
347423b2 78 // remember current state of depth
79 // function and change its value
80 GLint aDepthFuncPrev;
81 glGetIntegerv (GL_DEPTH_FUNC, &aDepthFuncPrev);
82 glDepthFunc (GL_LESS);
83
4269bd1b 84 // generate capping for every clip plane
85 for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next())
86 {
87 // get plane being rendered
88 const Handle(Graphic3d_ClipPlane)& aRenderPlane = aCappingIt.Value();
89 if (!aRenderPlane->IsCapping())
90 {
91 continue;
92 }
93
94 // enable only the rendering plane to generate stencil mask
51b10cd4 95 Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aContextPlanes);
4269bd1b 96 for (; aPlaneIt.More(); aPlaneIt.Next())
97 {
98 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
99 const Standard_Boolean isOn = (aPlane == aRenderPlane);
79f4f036 100 aContext->ChangeClipping().SetEnabled (aContext, aPlane, isOn);
4269bd1b 101 }
deb02f86 102 aContext->ShaderManager()->UpdateClippingState();
4269bd1b 103
104 glClear (GL_STENCIL_BUFFER_BIT);
105 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
106
107 // override aspects, disable culling
f8ae3605 108 theWorkspace->SetAspectFace (&theWorkspace->NoneCulling());
f9ba5c4d 109 theWorkspace->ApplyAspectFace();
4269bd1b 110
111 // evaluate number of pair faces
112 glDisable (GL_DEPTH_TEST);
113 glDepthMask (GL_FALSE);
114 glStencilFunc (GL_ALWAYS, 1, 0x01);
115 glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT);
116
cc6852f3 117 // render closed primitives
118 theStructure.renderClosedGeometry (theWorkspace);
4269bd1b 119
b859a34d 120 // override material, cull back faces
f8ae3605 121 theWorkspace->SetAspectFace (&theWorkspace->FrontCulling());
f9ba5c4d 122 theWorkspace->ApplyAspectFace();
4269bd1b 123
124 // enable all clip plane except the rendered one
125 for (aPlaneIt.Init (aContextPlanes); aPlaneIt.More(); aPlaneIt.Next())
126 {
127 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
128 const Standard_Boolean isOn = (aPlane != aRenderPlane);
79f4f036 129 aContext->ChangeClipping().SetEnabled (aContext, aPlane, isOn);
4269bd1b 130 }
deb02f86 131 aContext->ShaderManager()->UpdateClippingState();
4269bd1b 132
133 // render capping plane using the generated stencil mask
134 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
135 glDepthMask (GL_TRUE);
4269bd1b 136 glStencilFunc (GL_EQUAL, 1, 0x01);
137 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
138 glEnable (GL_DEPTH_TEST);
139
140 RenderPlane (theWorkspace, aRenderPlane);
deb02f86 141
142 aContext->ShaderManager()->RevertClippingState();
143 aContext->ShaderManager()->RevertClippingState();
4269bd1b 144 }
145
146 // restore previous application state
147 glClear (GL_STENCIL_BUFFER_BIT);
347423b2 148 glDepthFunc (aDepthFuncPrev);
4269bd1b 149 glStencilFunc (GL_ALWAYS, 0, 0xFF);
150 glDisable (GL_STENCIL_TEST);
151
152 // enable clipping
153 for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next())
154 {
79f4f036 155 aContext->ChangeClipping().SetEnabled (aContext, aCappingIt.Value(), Standard_True);
4269bd1b 156 }
157
158 // restore rendering aspects
159 theWorkspace->SetAspectFace (aFaceAsp);
160 theWorkspace->SetRenderFilter (aRenderFilter);
161}
162
163// =======================================================================
164// function : RenderPlane
165// purpose :
166// =======================================================================
167void OpenGl_CappingAlgo::RenderPlane (const Handle(OpenGl_Workspace)& theWorkspace,
168 const Handle(Graphic3d_ClipPlane)& thePlane)
169{
170 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
171
172 // get resource for the plane
173 TCollection_AsciiString aResId = thePlane->GetId();
174
175 Handle(OpenGl_CappingPlaneResource) aPlaneRes;
176 if (!aContext->GetResource (aResId, aPlaneRes))
177 {
178 // share and register for release once the resource is no longer used
179 aPlaneRes = new OpenGl_CappingPlaneResource (thePlane);
180 aContext->ShareResource (aResId, aPlaneRes);
181 }
182
183 aPlaneRes->Update (aContext);
184
f9ba5c4d 185 const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace();
4269bd1b 186 const OpenGl_AspectFace* aPlaneAspect = aPlaneRes->AspectFace();
187 if (aPlaneAspect != NULL)
188 {
189 theWorkspace->SetAspectFace (aPlaneAspect);
190 }
191
4269bd1b 192 // set identity model matrix
c827ea3a 193 aContext->ModelWorldState.Push();
194 aContext->ModelWorldState.SetCurrent (OpenGl_Mat4::Map (*aPlaneRes->Orientation()->mat));
195 aContext->ApplyModelViewMatrix();
196
e1c659da 197 aPlaneRes->Primitives().Render (theWorkspace);
4269bd1b 198
c827ea3a 199 aContext->ModelWorldState.Pop();
200 aContext->ApplyModelViewMatrix();
201
4269bd1b 202 theWorkspace->SetAspectFace (aFaceAspect);
203
204 // set delayed resource release
205 aPlaneRes.Nullify();
206 aContext->ReleaseResource (aResId, Standard_True);
207}
208
209// =======================================================================
4269bd1b 210// function : CanRender
211// purpose :
212// =======================================================================
213Standard_Boolean OpenGl_CappingAlgoFilter::CanRender (const OpenGl_Element* theElement)
214{
871fa103 215 const OpenGl_PrimitiveArray* aPArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
216 return aPArray != NULL
ca3c13d1 217 && aPArray->DrawMode() >= THE_FILLPRIM_FROM
218 && aPArray->DrawMode() <= THE_FILLPRIM_TO;
4269bd1b 219}