0027961: Visualization - remove unused and no more working OpenGl_AVIWriter
[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
3e05329c 37
38 //! Render infinite capping plane.
39 //! @param theWorkspace [in] the GL workspace, context state.
40 //! @param thePlane [in] the graphical plane, for which the capping surface is rendered.
41 static void renderPlane (const Handle(OpenGl_Workspace)& theWorkspace,
42 const Handle(OpenGl_CappingPlaneResource)& thePlane,
43 const OpenGl_AspectFace* theAspectFace)
44 {
45 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
46 thePlane->Update (aContext, theAspectFace != NULL ? theAspectFace->Aspect() : Handle(Graphic3d_AspectFillArea3d)());
47
48 const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace();
49 theWorkspace->SetAspectFace (thePlane->AspectFace());
50
51 // set identity model matrix
52 aContext->ModelWorldState.Push();
53 aContext->ModelWorldState.SetCurrent (OpenGl_Mat4::Map (*thePlane->Orientation()->mat));
54 aContext->ApplyModelViewMatrix();
55
56 thePlane->Primitives().Render (theWorkspace);
57
58 aContext->ModelWorldState.Pop();
59 aContext->ApplyModelViewMatrix();
60
61 theWorkspace->SetAspectFace (aFaceAspect);
62 }
63
64 //! Render capping for specific structure.
65 static void renderCappingForStructure (const Handle(OpenGl_Workspace)& theWorkspace,
66 const OpenGl_Structure& theStructure,
3202bf1e 67 const OpenGl_ClippingIterator& thePlaneIter,
3e05329c 68 const Handle(OpenGl_CappingPlaneResource)& thePlane)
69 {
3202bf1e 70 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
71 const Handle(Graphic3d_ClipPlane)& aRenderPlane = thePlane->Plane();
3e05329c 72 for (OpenGl_Structure::GroupIterator aGroupIter (theStructure.Groups()); aGroupIter.More(); aGroupIter.Next())
73 {
74 if (!aGroupIter.Value()->IsClosed())
75 {
76 continue;
77 }
78
79 // enable only the rendering plane to generate stencil mask
3202bf1e 80 aContext->ChangeClipping().DisableAllExcept (aContext, thePlaneIter);
3e05329c 81 aContext->ShaderManager()->UpdateClippingState();
82
83 glClear (GL_STENCIL_BUFFER_BIT);
84 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
85
86 // override aspects, disable culling
87 theWorkspace->SetAspectFace (&theWorkspace->NoneCulling());
88 theWorkspace->ApplyAspectFace();
89
90 // evaluate number of pair faces
91 glDisable (GL_DEPTH_TEST);
92 glDepthMask (GL_FALSE);
93 glStencilFunc (GL_ALWAYS, 1, 0x01);
94 glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT);
95
96 // render closed primitives
97 if (aRenderPlane->ToUseObjectProperties())
98 {
99 aGroupIter.Value()->Render (theWorkspace);
100 }
101 else
102 {
103 for (; aGroupIter.More(); aGroupIter.Next())
104 {
105 if (aGroupIter.Value()->IsClosed())
106 {
107 aGroupIter.Value()->Render (theWorkspace);
108 }
109 }
110 }
111
112 // override material, cull back faces
113 theWorkspace->SetAspectFace (&theWorkspace->FrontCulling());
114 theWorkspace->ApplyAspectFace();
115
116 // enable all clip plane except the rendered one
3202bf1e 117 aContext->ChangeClipping().EnableAllExcept (aContext, thePlaneIter);
3e05329c 118 aContext->ShaderManager()->UpdateClippingState();
119
120 // render capping plane using the generated stencil mask
121 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
122 glDepthMask (GL_TRUE);
123 glStencilFunc (GL_EQUAL, 1, 0x01);
124 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
125 glEnable (GL_DEPTH_TEST);
126
127 renderPlane (theWorkspace, thePlane, aRenderPlane->ToUseObjectProperties()
128 ? aGroupIter.Value()->AspectFace()
129 : NULL);
130
3202bf1e 131 // turn on the current plane to restore initial state
132 aContext->ChangeClipping().SetEnabled (aContext, thePlaneIter, Standard_True);
3e05329c 133 aContext->ShaderManager()->RevertClippingState();
134 aContext->ShaderManager()->RevertClippingState();
135 }
136
137 if (theStructure.InstancedStructure() != NULL)
138 {
3202bf1e 139 renderCappingForStructure (theWorkspace, *theStructure.InstancedStructure(), thePlaneIter, thePlane);
3e05329c 140 }
141 }
ca3c13d1 142}
4269bd1b 143
144// =======================================================================
145// function : RenderCapping
146// purpose :
147// =======================================================================
cc6852f3 148void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace,
149 const OpenGl_Structure& theStructure)
4269bd1b 150{
4269bd1b 151 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
3202bf1e 152 if (!aContext->Clipping().IsCappingOn())
b859a34d 153 {
3202bf1e 154 // do not perform algorithm if there is nothing to render
4269bd1b 155 return;
b859a34d 156 }
4269bd1b 157
4269bd1b 158 // remember current aspect face defined in workspace
f9ba5c4d 159 const OpenGl_AspectFace* aFaceAsp = theWorkspace->AspectFace();
4269bd1b 160
161 // replace primitive groups rendering filter
4269bd1b 162 Handle(OpenGl_RenderFilter) aRenderFilter = theWorkspace->GetRenderFilter();
f8ae3605 163 theWorkspace->SetRenderFilter (theWorkspace->DefaultCappingAlgoFilter());
4269bd1b 164
165 // prepare for rendering the clip planes
166 glEnable (GL_STENCIL_TEST);
167
347423b2 168 // remember current state of depth
169 // function and change its value
170 GLint aDepthFuncPrev;
171 glGetIntegerv (GL_DEPTH_FUNC, &aDepthFuncPrev);
172 glDepthFunc (GL_LESS);
173
4269bd1b 174 // generate capping for every clip plane
3202bf1e 175 for (OpenGl_ClippingIterator aCappingIt (aContext->Clipping()); aCappingIt.More(); aCappingIt.Next())
4269bd1b 176 {
177 // get plane being rendered
178 const Handle(Graphic3d_ClipPlane)& aRenderPlane = aCappingIt.Value();
3202bf1e 179 if (!aRenderPlane->IsCapping()
180 || aCappingIt.IsDisabled())
4269bd1b 181 {
182 continue;
183 }
184
3e05329c 185 // get resource for the plane
186 const TCollection_AsciiString& aResId = aRenderPlane->GetId();
187 Handle(OpenGl_CappingPlaneResource) aPlaneRes;
188 if (!aContext->GetResource (aResId, aPlaneRes))
4269bd1b 189 {
3e05329c 190 // share and register for release once the resource is no longer used
191 aPlaneRes = new OpenGl_CappingPlaneResource (aRenderPlane);
192 aContext->ShareResource (aResId, aPlaneRes);
4269bd1b 193 }
4269bd1b 194
3202bf1e 195 renderCappingForStructure (theWorkspace, theStructure, aCappingIt, aPlaneRes);
4269bd1b 196
3e05329c 197 // set delayed resource release
198 aPlaneRes.Nullify();
199 aContext->ReleaseResource (aResId, Standard_True);
4269bd1b 200 }
201
202 // restore previous application state
203 glClear (GL_STENCIL_BUFFER_BIT);
347423b2 204 glDepthFunc (aDepthFuncPrev);
4269bd1b 205 glStencilFunc (GL_ALWAYS, 0, 0xFF);
206 glDisable (GL_STENCIL_TEST);
207
4269bd1b 208 // restore rendering aspects
209 theWorkspace->SetAspectFace (aFaceAsp);
210 theWorkspace->SetRenderFilter (aRenderFilter);
211}
212
213// =======================================================================
4269bd1b 214// function : CanRender
215// purpose :
216// =======================================================================
217Standard_Boolean OpenGl_CappingAlgoFilter::CanRender (const OpenGl_Element* theElement)
218{
871fa103 219 const OpenGl_PrimitiveArray* aPArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
220 return aPArray != NULL
ca3c13d1 221 && aPArray->DrawMode() >= THE_FILLPRIM_FROM
222 && aPArray->DrawMode() <= THE_FILLPRIM_TO;
4269bd1b 223}