Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-08-01 |
2 | // Created by: Sergey ZERCHANINOV | |
973c2be1 | 3 | // Copyright (c) 2011-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 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. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
b311480e | 15 | |
4269bd1b | 16 | #include <OpenGl_CappingAlgo.hxx> |
17 | #include <OpenGl_Context.hxx> | |
30f0ad28 | 18 | #include <OpenGl_GlCore11.hxx> |
63bcc448 | 19 | #include <OpenGl_GraphicDriver.hxx> |
30f0ad28 | 20 | #include <OpenGl_ShaderManager.hxx> |
21 | #include <OpenGl_ShaderProgram.hxx> | |
2bd4bfac | 22 | #include <OpenGl_StructureShadow.hxx> |
30f0ad28 | 23 | #include <OpenGl_Vec.hxx> |
24 | #include <OpenGl_View.hxx> | |
25 | #include <OpenGl_Workspace.hxx> | |
2166f0fa | 26 | |
494782f6 | 27 | #include <Graphic3d_SequenceOfHClipPlane.hxx> |
b859a34d | 28 | |
63bcc448 | 29 | |
92efcf78 | 30 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Structure,Graphic3d_CStructure) |
31 | ||
27eed937 | 32 | //! Auxiliary class for bounding box presentation |
33 | class OpenGl_BndBoxPrs : public OpenGl_Element | |
34 | { | |
35 | ||
36 | public: | |
37 | ||
38 | //! Main constructor | |
7c3ef2f7 | 39 | OpenGl_BndBoxPrs (const Graphic3d_BndBox3d& theBndBox) |
b7cd4ba7 | 40 | { |
7c3ef2f7 | 41 | const float Xm = (float )theBndBox.CornerMin().x(); |
42 | const float Ym = (float)theBndBox.CornerMin().y(); | |
43 | const float Zm = (float)theBndBox.CornerMin().z(); | |
44 | const float XM = (float)theBndBox.CornerMax().x(); | |
45 | const float YM = (float)theBndBox.CornerMax().y(); | |
46 | const float ZM = (float)theBndBox.CornerMax().z(); | |
b7cd4ba7 | 47 | |
27eed937 | 48 | myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm); |
49 | myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM); | |
50 | myVerts[2] = OpenGl_Vec3 (Xm, YM, ZM); | |
51 | myVerts[3] = OpenGl_Vec3 (Xm, YM, Zm); | |
52 | myVerts[4] = OpenGl_Vec3 (Xm, Ym, Zm); | |
53 | myVerts[5] = OpenGl_Vec3 (XM, Ym, Zm); | |
54 | myVerts[6] = OpenGl_Vec3 (XM, Ym, ZM); | |
55 | myVerts[7] = OpenGl_Vec3 (XM, YM, ZM); | |
56 | myVerts[8] = OpenGl_Vec3 (XM, YM, Zm); | |
57 | myVerts[9] = OpenGl_Vec3 (XM, Ym, Zm); | |
58 | myVerts[10] = OpenGl_Vec3 (XM, YM, Zm); | |
59 | myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm); | |
60 | myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM); | |
61 | myVerts[13] = OpenGl_Vec3 (XM, YM, ZM); | |
62 | myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM); | |
63 | myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM); | |
64 | } | |
65 | ||
66 | //! Render presentation | |
67 | virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const | |
68 | { | |
ca3c13d1 | 69 | #if !defined(GL_ES_VERSION_2_0) |
27eed937 | 70 | // Apply line aspect |
27eed937 | 71 | const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture(); |
72 | ||
8613985b | 73 | theWorkspace->GetGlContext()->BindProgram (Handle(OpenGl_ShaderProgram)()); |
74 | theWorkspace->GetGlContext()->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)()); | |
75 | ||
27eed937 | 76 | glDisable (GL_LIGHTING); |
27eed937 | 77 | |
78 | // Use highlight colors | |
b6472664 | 79 | theWorkspace->GetGlContext()->core11->glColor3fv (theWorkspace->LineColor().GetData()); |
27eed937 | 80 | |
81 | glEnableClientState (GL_VERTEX_ARRAY); | |
82 | glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts); | |
83 | glDrawArrays (GL_LINE_STRIP, 0, 16); | |
84 | glDisableClientState (GL_VERTEX_ARRAY); | |
85 | ||
86 | // restore aspects | |
87 | if (!aPrevTexture.IsNull()) | |
88 | { | |
89 | theWorkspace->EnableTexture (aPrevTexture); | |
90 | } | |
20aeeb7b | 91 | #else |
92 | (void )theWorkspace; | |
ca3c13d1 | 93 | #endif |
27eed937 | 94 | } |
95 | ||
96 | //! Release graphical resources | |
10b9c7df | 97 | virtual void Release (OpenGl_Context*) |
27eed937 | 98 | { |
99 | // | |
100 | } | |
101 | ||
102 | protected: | |
103 | ||
104 | //! Protected destructor | |
105 | virtual ~OpenGl_BndBoxPrs() {} | |
106 | ||
107 | private: | |
108 | ||
109 | OpenGl_Vec3 myVerts[16]; //!< vertices array | |
110 | ||
111 | public: | |
112 | ||
113 | DEFINE_STANDARD_ALLOC | |
114 | ||
115 | }; | |
2166f0fa SK |
116 | |
117 | /*----------------------------------------------------------------------*/ | |
118 | ||
4269bd1b | 119 | // ======================================================================= |
120 | // function : OpenGl_Structure | |
121 | // purpose : | |
122 | // ======================================================================= | |
63bcc448 | 123 | OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager) |
124 | : Graphic3d_CStructure (theManager), | |
d4aaad5b | 125 | myInstancedStructure (NULL), |
126 | myIsRaytracable (Standard_False), | |
127 | myModificationState (0), | |
128 | myIsCulled (Standard_True), | |
129 | myIsMirrored (Standard_False) | |
2166f0fa | 130 | { |
7c3ef2f7 | 131 | updateLayerTransformation(); |
2166f0fa SK |
132 | } |
133 | ||
4269bd1b | 134 | // ======================================================================= |
135 | // function : ~OpenGl_Structure | |
136 | // purpose : | |
137 | // ======================================================================= | |
5e27df78 | 138 | OpenGl_Structure::~OpenGl_Structure() |
2166f0fa | 139 | { |
5e27df78 | 140 | Release (Handle(OpenGl_Context)()); |
2166f0fa SK |
141 | } |
142 | ||
7c3ef2f7 | 143 | // ======================================================================= |
144 | // function : SetZLayer | |
145 | // purpose : | |
146 | // ======================================================================= | |
147 | void OpenGl_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerIndex) | |
148 | { | |
149 | Graphic3d_CStructure::SetZLayer (theLayerIndex); | |
150 | updateLayerTransformation(); | |
151 | } | |
152 | ||
63bcc448 | 153 | // ======================================================================= |
1f7f5a90 | 154 | // function : SetTransformation |
63bcc448 | 155 | // purpose : |
156 | // ======================================================================= | |
1f7f5a90 | 157 | void OpenGl_Structure::SetTransformation (const Handle(Geom_Transformation)& theTrsf) |
63bcc448 | 158 | { |
1f7f5a90 | 159 | myTrsf = theTrsf; |
160 | myIsMirrored = Standard_False; | |
161 | if (!myTrsf.IsNull()) | |
162 | { | |
163 | // Determinant of transform matrix less then 0 means that mirror transform applied. | |
164 | const Standard_Real aDet = myTrsf->Value(1, 1) * (myTrsf->Value (2, 2) * myTrsf->Value (3, 3) - myTrsf->Value (3, 2) * myTrsf->Value (2, 3)) | |
165 | - myTrsf->Value(1, 2) * (myTrsf->Value (2, 1) * myTrsf->Value (3, 3) - myTrsf->Value (3, 1) * myTrsf->Value (2, 3)) | |
166 | + myTrsf->Value(1, 3) * (myTrsf->Value (2, 1) * myTrsf->Value (3, 2) - myTrsf->Value (3, 1) * myTrsf->Value (2, 2)); | |
167 | myIsMirrored = aDet < 0.0; | |
168 | } | |
7d9e854b | 169 | |
7c3ef2f7 | 170 | updateLayerTransformation(); |
d4aaad5b | 171 | if (IsRaytracable()) |
e276548b | 172 | { |
d4aaad5b | 173 | ++myModificationState; |
e276548b | 174 | } |
2166f0fa SK |
175 | } |
176 | ||
7c3ef2f7 | 177 | // ======================================================================= |
178 | // function : SetTransformPersistence | |
179 | // purpose : | |
180 | // ======================================================================= | |
181 | void OpenGl_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) | |
182 | { | |
183 | myTrsfPers = theTrsfPers; | |
184 | updateLayerTransformation(); | |
185 | } | |
186 | ||
187 | // ======================================================================= | |
188 | // function : updateLayerTransformation | |
189 | // purpose : | |
190 | // ======================================================================= | |
191 | void OpenGl_Structure::updateLayerTransformation() | |
192 | { | |
193 | gp_Trsf aRenderTrsf; | |
194 | if (!myTrsf.IsNull()) | |
195 | { | |
196 | aRenderTrsf = myTrsf->Trsf(); | |
197 | } | |
198 | ||
199 | const Graphic3d_ZLayerSettings& aLayer = myGraphicDriver->ZLayerSettings (myZLayer); | |
200 | if (!aLayer.OriginTransformation().IsNull() | |
201 | && myTrsfPers.IsNull()) | |
202 | { | |
203 | aRenderTrsf.SetTranslationPart (aRenderTrsf.TranslationPart() - aLayer.Origin()); | |
204 | } | |
205 | aRenderTrsf.GetMat4 (myRenderTrsf); | |
206 | } | |
207 | ||
4269bd1b | 208 | // ======================================================================= |
b64d84be | 209 | // function : clearHighlightBox |
4269bd1b | 210 | // purpose : |
211 | // ======================================================================= | |
b64d84be | 212 | void OpenGl_Structure::clearHighlightBox (const Handle(OpenGl_Context)& theGlCtx) |
2166f0fa | 213 | { |
b64d84be | 214 | if (!myHighlightBox.IsNull()) |
5e27df78 | 215 | { |
216 | myHighlightBox->Release (theGlCtx); | |
b64d84be | 217 | myHighlightBox.Nullify(); |
2166f0fa SK |
218 | } |
219 | } | |
220 | ||
63bcc448 | 221 | // ======================================================================= |
222 | // function : HighlightWithBndBox | |
223 | // purpose : | |
224 | // ======================================================================= | |
8e5fb5ea | 225 | void OpenGl_Structure::highlightWithBndBox (const Handle(Graphic3d_Structure)& theStruct) |
63bcc448 | 226 | { |
7d9e854b | 227 | const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext(); |
b64d84be | 228 | |
229 | if (!myHighlightBox.IsNull()) | |
230 | { | |
7d9e854b | 231 | myHighlightBox->Release (aContext); |
b64d84be | 232 | } |
63bcc448 | 233 | else |
b64d84be | 234 | { |
235 | myHighlightBox = new OpenGl_Group (theStruct); | |
236 | } | |
237 | ||
8e5fb5ea | 238 | myHighlightBox->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (myHighlightStyle->Color(), Aspect_TOL_SOLID, 1.0)); |
b64d84be | 239 | |
b7cd4ba7 | 240 | OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox); |
b64d84be | 241 | myHighlightBox->AddElement (aBndBoxPrs); |
63bcc448 | 242 | } |
243 | ||
4269bd1b | 244 | // ======================================================================= |
8e5fb5ea | 245 | // function : GraphicHighlight |
4269bd1b | 246 | // purpose : |
247 | // ======================================================================= | |
f838dac4 | 248 | void OpenGl_Structure::GraphicHighlight (const Handle(Graphic3d_PresentationAttributes)& theStyle, |
249 | const Handle(Graphic3d_Structure)& theStruct) | |
2166f0fa | 250 | { |
424392e0 | 251 | if (!myHighlightStyle.IsNull() |
252 | && myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX | |
253 | && theStyle->Method() != Aspect_TOHM_BOUNDBOX) | |
254 | { | |
255 | const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext(); | |
256 | clearHighlightBox (aContext); | |
257 | } | |
258 | ||
8e5fb5ea | 259 | myHighlightStyle = theStyle; |
260 | ||
261 | highlight = 1; | |
262 | if (myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX) | |
b6472664 | 263 | { |
8e5fb5ea | 264 | highlightWithBndBox (theStruct); |
5e27df78 | 265 | } |
2166f0fa SK |
266 | } |
267 | ||
4269bd1b | 268 | // ======================================================================= |
8e5fb5ea | 269 | // function : GraphicUnhighlight |
4269bd1b | 270 | // purpose : |
271 | // ======================================================================= | |
8e5fb5ea | 272 | void OpenGl_Structure::GraphicUnhighlight() |
2166f0fa | 273 | { |
8e5fb5ea | 274 | highlight = 0; |
275 | ||
276 | if (myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX) | |
277 | { | |
278 | const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext(); | |
279 | clearHighlightBox (aContext); | |
280 | } | |
281 | ||
282 | myHighlightStyle.Nullify(); | |
2166f0fa SK |
283 | } |
284 | ||
e276548b | 285 | // ======================================================================= |
a1954302 | 286 | // function : OnVisibilityChanged |
e276548b | 287 | // purpose : |
288 | // ======================================================================= | |
a1954302 | 289 | void OpenGl_Structure::OnVisibilityChanged() |
e276548b | 290 | { |
d4aaad5b | 291 | if (IsRaytracable()) |
e276548b | 292 | { |
d4aaad5b | 293 | ++myModificationState; |
e276548b | 294 | } |
e276548b | 295 | } |
296 | ||
e276548b | 297 | // ======================================================================= |
d4aaad5b | 298 | // function : IsRaytracable |
e276548b | 299 | // purpose : |
300 | // ======================================================================= | |
d4aaad5b | 301 | Standard_Boolean OpenGl_Structure::IsRaytracable() const |
e276548b | 302 | { |
3e05329c | 303 | if (!myGroups.IsEmpty() |
304 | && myIsRaytracable) | |
e276548b | 305 | { |
3e05329c | 306 | return Standard_True; |
e276548b | 307 | } |
d5af8626 | 308 | |
3e05329c | 309 | return myInstancedStructure != NULL |
310 | && myInstancedStructure->IsRaytracable(); | |
d5af8626 | 311 | } |
312 | ||
e276548b | 313 | // ======================================================================= |
d4aaad5b | 314 | // function : UpdateRaytracableState |
e276548b | 315 | // purpose : |
316 | // ======================================================================= | |
d4aaad5b | 317 | void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const |
e276548b | 318 | { |
3e05329c | 319 | myIsRaytracable = !toCheck; |
320 | if (!myIsRaytracable) | |
321 | { | |
322 | for (OpenGl_Structure::GroupIterator anIter (myGroups); anIter.More(); anIter.Next()) | |
323 | { | |
324 | if (anIter.Value()->IsRaytracable()) | |
325 | { | |
326 | myIsRaytracable = Standard_True; | |
327 | break; | |
328 | } | |
329 | } | |
330 | } | |
e276548b | 331 | |
d4aaad5b | 332 | if (IsRaytracable()) |
e276548b | 333 | { |
d4aaad5b | 334 | ++myModificationState; |
e276548b | 335 | } |
336 | } | |
337 | ||
4269bd1b | 338 | // ======================================================================= |
339 | // function : Connect | |
340 | // purpose : | |
341 | // ======================================================================= | |
63bcc448 | 342 | void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure) |
2166f0fa | 343 | { |
d4aaad5b | 344 | OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure); |
345 | ||
346 | Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct, | |
347 | "Error! Instanced structure is already defined"); | |
348 | ||
349 | myInstancedStructure = aStruct; | |
e276548b | 350 | |
63bcc448 | 351 | if (aStruct->IsRaytracable()) |
e276548b | 352 | { |
d4aaad5b | 353 | UpdateStateIfRaytracable (Standard_False); |
e276548b | 354 | } |
2166f0fa SK |
355 | } |
356 | ||
4269bd1b | 357 | // ======================================================================= |
358 | // function : Disconnect | |
359 | // purpose : | |
360 | // ======================================================================= | |
63bcc448 | 361 | void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure) |
2166f0fa | 362 | { |
d4aaad5b | 363 | OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure); |
e276548b | 364 | |
d4aaad5b | 365 | if (myInstancedStructure == aStruct) |
366 | { | |
367 | myInstancedStructure = NULL; | |
e276548b | 368 | |
d4aaad5b | 369 | if (aStruct->IsRaytracable()) |
370 | { | |
371 | UpdateStateIfRaytracable(); | |
2166f0fa | 372 | } |
2166f0fa SK |
373 | } |
374 | } | |
375 | ||
4269bd1b | 376 | // ======================================================================= |
b64d84be | 377 | // function : NewGroup |
4269bd1b | 378 | // purpose : |
379 | // ======================================================================= | |
b64d84be | 380 | Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Structure)& theStruct) |
2166f0fa | 381 | { |
b64d84be | 382 | Handle(OpenGl_Group) aGroup = new OpenGl_Group (theStruct); |
383 | myGroups.Append (aGroup); | |
384 | return aGroup; | |
2166f0fa SK |
385 | } |
386 | ||
4269bd1b | 387 | // ======================================================================= |
388 | // function : RemoveGroup | |
389 | // purpose : | |
390 | // ======================================================================= | |
b64d84be | 391 | void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup) |
2166f0fa | 392 | { |
b64d84be | 393 | if (theGroup.IsNull()) |
394 | { | |
395 | return; | |
396 | } | |
397 | ||
398 | for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) | |
2166f0fa SK |
399 | { |
400 | // Check for the given group | |
b64d84be | 401 | if (aGroupIter.Value() == theGroup) |
2166f0fa | 402 | { |
d4aaad5b | 403 | const Standard_Boolean wasRaytracable = |
404 | static_cast<const OpenGl_Group&> (*theGroup).IsRaytracable(); | |
405 | ||
b64d84be | 406 | theGroup->Clear (Standard_False); |
e276548b | 407 | |
d4aaad5b | 408 | if (wasRaytracable) |
e276548b | 409 | { |
d4aaad5b | 410 | UpdateStateIfRaytracable(); |
e276548b | 411 | } |
e276548b | 412 | |
b64d84be | 413 | myGroups.Remove (aGroupIter); |
2166f0fa SK |
414 | return; |
415 | } | |
2166f0fa SK |
416 | } |
417 | } | |
418 | ||
63bcc448 | 419 | // ======================================================================= |
420 | // function : Clear | |
421 | // purpose : | |
422 | // ======================================================================= | |
423 | void OpenGl_Structure::Clear() | |
424 | { | |
425 | Clear (GlDriver()->GetSharedContext()); | |
426 | } | |
427 | ||
4269bd1b | 428 | // ======================================================================= |
429 | // function : Clear | |
430 | // purpose : | |
431 | // ======================================================================= | |
5e27df78 | 432 | void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx) |
2166f0fa | 433 | { |
e276548b | 434 | Standard_Boolean aRaytracableGroupDeleted (Standard_False); |
e276548b | 435 | |
5e27df78 | 436 | // Release groups |
b64d84be | 437 | for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) |
2166f0fa | 438 | { |
b64d84be | 439 | aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable(); |
5322131b | 440 | |
2166f0fa | 441 | // Delete objects |
b64d84be | 442 | aGroupIter.ChangeValue()->Release (theGlCtx); |
2166f0fa SK |
443 | } |
444 | myGroups.Clear(); | |
e276548b | 445 | |
e276548b | 446 | if (aRaytracableGroupDeleted) |
447 | { | |
d4aaad5b | 448 | myIsRaytracable = Standard_False; |
e276548b | 449 | } |
b7cd4ba7 | 450 | |
451 | Is2dText = Standard_False; | |
452 | IsForHighlight = Standard_False; | |
2166f0fa SK |
453 | } |
454 | ||
0717ddc1 | 455 | // ======================================================================= |
cc6852f3 | 456 | // function : renderGeometry |
0717ddc1 | 457 | // purpose : |
458 | // ======================================================================= | |
cc6852f3 | 459 | void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace, |
460 | bool& theHasClosed) const | |
0717ddc1 | 461 | { |
cc6852f3 | 462 | if (myInstancedStructure != NULL) |
0717ddc1 | 463 | { |
cc6852f3 | 464 | myInstancedStructure->renderGeometry (theWorkspace, theHasClosed); |
465 | } | |
466 | ||
467 | for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) | |
468 | { | |
469 | theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed(); | |
7d9e854b | 470 | aGroupIter.Value()->Render (theWorkspace); |
0717ddc1 | 471 | } |
472 | } | |
cc6852f3 | 473 | |
4269bd1b | 474 | // ======================================================================= |
475 | // function : Render | |
476 | // purpose : | |
477 | // ======================================================================= | |
7d9e854b | 478 | void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) const |
2166f0fa SK |
479 | { |
480 | // Process the structure only if visible | |
a1954302 | 481 | if (!visible) |
7d9e854b | 482 | { |
2166f0fa | 483 | return; |
7d9e854b | 484 | } |
2166f0fa | 485 | |
c827ea3a | 486 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); |
b7cd4ba7 | 487 | |
2166f0fa | 488 | // Render named status |
8e5fb5ea | 489 | if (highlight && myHighlightBox.IsNull()) |
a1954302 | 490 | { |
f838dac4 | 491 | theWorkspace->SetHighlightStyle (myHighlightStyle); |
a1954302 | 492 | } |
2166f0fa | 493 | |
2166f0fa | 494 | // Apply local transformation |
6bd94e0d | 495 | aCtx->ModelWorldState.Push(); |
1f7f5a90 | 496 | OpenGl_Mat4& aModelWorld = aCtx->ModelWorldState.ChangeCurrent(); |
7c3ef2f7 | 497 | aModelWorld = myRenderTrsf; |
6bd94e0d | 498 | |
1d92133e | 499 | const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled(); |
1d92133e | 500 | #if !defined(GL_ES_VERSION_2_0) |
501 | // detect scale transform | |
1f7f5a90 | 502 | if (aCtx->core11 != NULL |
503 | && !myTrsf.IsNull()) | |
1d92133e | 504 | { |
1f7f5a90 | 505 | const Standard_Real aScale = myTrsf->ScaleFactor(); |
506 | if (Abs (aScale - 1.0) > Precision::Confusion()) | |
1d92133e | 507 | { |
508 | aCtx->SetGlNormalizeEnabled (Standard_True); | |
509 | } | |
510 | } | |
511 | #endif | |
512 | ||
778cd667 | 513 | if (!myTrsfPers.IsNull()) |
825aa485 | 514 | { |
825aa485 | 515 | aCtx->WorldViewState.Push(); |
7c3ef2f7 | 516 | OpenGl_Mat4& aWorldView = aCtx->WorldViewState.ChangeCurrent(); |
517 | myTrsfPers->Apply (theWorkspace->View()->Camera(), | |
518 | aCtx->ProjectionState.Current(), aWorldView, | |
56689b27 | 519 | aCtx->VirtualViewport()[2], aCtx->VirtualViewport()[3]); |
2166f0fa | 520 | |
1d92133e | 521 | #if !defined(GL_ES_VERSION_2_0) |
522 | if (!aCtx->IsGlNormalizeEnabled() | |
523 | && aCtx->core11 != NULL) | |
524 | { | |
525 | const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor<Standard_ShortReal> (aWorldView); | |
7c3ef2f7 | 526 | if (Abs (aScale - 1.0) > Precision::Confusion()) |
1d92133e | 527 | { |
528 | aCtx->SetGlNormalizeEnabled (Standard_True); | |
529 | } | |
530 | } | |
531 | #endif | |
04be5003 | 532 | } |
533 | ||
d437b80d | 534 | // Take into account transform persistence |
535 | aCtx->ApplyModelViewMatrix(); | |
c827ea3a | 536 | |
f9ba5c4d | 537 | // remember aspects |
538 | const OpenGl_AspectLine* aPrevAspectLine = theWorkspace->AspectLine(); | |
539 | const OpenGl_AspectFace* aPrevAspectFace = theWorkspace->AspectFace(); | |
540 | const OpenGl_AspectMarker* aPrevAspectMarker = theWorkspace->AspectMarker(); | |
541 | const OpenGl_AspectText* aPrevAspectText = theWorkspace->AspectText(); | |
7d9e854b | 542 | |
543 | // Apply correction for mirror transform | |
544 | if (myIsMirrored) | |
545 | { | |
c827ea3a | 546 | aCtx->core11fwd->glFrontFace (GL_CW); |
7d9e854b | 547 | } |
2166f0fa | 548 | |
b859a34d | 549 | // Collect clipping planes of structure scope |
3202bf1e | 550 | aCtx->ChangeClipping().SetLocalPlanes (aCtx, myClipPlanes); |
4269bd1b | 551 | |
1a7ece8f | 552 | // True if structure is fully clipped |
553 | bool isClipped = false; | |
3202bf1e | 554 | bool hasDisabled = false; |
555 | if (aCtx->Clipping().IsClippingOrCappingOn()) | |
1a7ece8f | 556 | { |
7c3ef2f7 | 557 | const Graphic3d_BndBox3d& aBBox = BoundingBox(); |
8b1441e3 | 558 | if (!myClipPlanes.IsNull() |
559 | && myClipPlanes->ToOverrideGlobal()) | |
1a7ece8f | 560 | { |
3202bf1e | 561 | aCtx->ChangeClipping().DisableGlobal (aCtx); |
562 | hasDisabled = aCtx->Clipping().HasDisabled(); | |
563 | } | |
8b1441e3 | 564 | else if (!myTrsfPers.IsNull()) |
565 | { | |
566 | if (myTrsfPers->IsZoomOrRotate()) | |
567 | { | |
568 | // Zoom/rotate persistence object lives in two worlds at the same time. | |
569 | // Global clipping planes can not be trivially applied without being converted | |
570 | // into local space of transformation persistence object. | |
571 | // As more simple alternative - just clip entire object by its anchor point defined in the world space. | |
572 | const gp_Pnt anAnchor = myTrsfPers->AnchorPoint(); | |
573 | for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More() && aPlaneIt.IsGlobal(); aPlaneIt.Next()) | |
574 | { | |
575 | const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); | |
576 | if (!aPlane->IsOn()) | |
577 | { | |
578 | continue; | |
579 | } | |
580 | ||
581 | // check for clipping | |
582 | const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation(); | |
583 | const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0); | |
584 | if (aPlaneEquation.Dot (aCheckPnt) < 0.0) // vertex is outside the half-space | |
585 | { | |
586 | isClipped = true; | |
587 | break; | |
588 | } | |
589 | } | |
590 | } | |
591 | ||
592 | aCtx->ChangeClipping().DisableGlobal (aCtx); | |
593 | hasDisabled = aCtx->Clipping().HasDisabled(); | |
594 | } | |
1a7ece8f | 595 | |
3202bf1e | 596 | // Set of clipping planes that do not intersect the structure, |
597 | // and thus can be disabled to improve rendering performance | |
598 | if (aBBox.IsValid() | |
778cd667 | 599 | && myTrsfPers.IsNull()) |
3202bf1e | 600 | { |
601 | for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More(); aPlaneIt.Next()) | |
1a7ece8f | 602 | { |
3202bf1e | 603 | const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); |
604 | if (!aPlane->IsOn()) | |
605 | { | |
606 | continue; | |
607 | } | |
1a7ece8f | 608 | |
3202bf1e | 609 | // check for clipping |
610 | const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation(); | |
611 | const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(), | |
612 | aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(), | |
613 | aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(), | |
614 | 1.0); | |
615 | if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space | |
616 | { | |
617 | isClipped = true; | |
618 | break; | |
619 | } | |
620 | ||
621 | // check for no intersection (e.g. object is "entirely not clipped") | |
622 | const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(), | |
623 | aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(), | |
624 | aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(), | |
625 | 1.0); | |
626 | if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space | |
1a7ece8f | 627 | { |
3202bf1e | 628 | aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt, Standard_False); |
629 | hasDisabled = true; | |
1a7ece8f | 630 | } |
1a7ece8f | 631 | } |
632 | } | |
3202bf1e | 633 | |
634 | if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty()) | |
635 | || hasDisabled) | |
636 | { | |
637 | // Set OCCT state uniform variables | |
638 | aCtx->ShaderManager()->UpdateClippingState(); | |
639 | } | |
1a7ece8f | 640 | } |
641 | ||
2166f0fa | 642 | // Render groups |
cc6852f3 | 643 | bool hasClosedPrims = false; |
1a7ece8f | 644 | if (!isClipped) |
645 | { | |
646 | renderGeometry (theWorkspace, hasClosedPrims); | |
647 | } | |
2166f0fa | 648 | |
7d9e854b | 649 | // Reset correction for mirror transform |
650 | if (myIsMirrored) | |
c827ea3a | 651 | { |
652 | aCtx->core11fwd->glFrontFace (GL_CCW); | |
653 | } | |
7d9e854b | 654 | |
b859a34d | 655 | // Render capping for structure groups |
cc6852f3 | 656 | if (hasClosedPrims |
1a7ece8f | 657 | && aCtx->Clipping().IsCappingOn()) |
b859a34d | 658 | { |
cc6852f3 | 659 | OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this); |
b859a34d | 660 | } |
4269bd1b | 661 | |
b859a34d | 662 | // Revert structure clippings |
3202bf1e | 663 | if (hasDisabled) |
1a7ece8f | 664 | { |
665 | // enable planes that were previously disabled | |
3202bf1e | 666 | aCtx->ChangeClipping().RestoreDisabled (aCtx); |
1a7ece8f | 667 | } |
3202bf1e | 668 | aCtx->ChangeClipping().SetLocalPlanes (aCtx, Handle(Graphic3d_SequenceOfHClipPlane)()); |
669 | if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty()) | |
670 | || hasDisabled) | |
4269bd1b | 671 | { |
30f0ad28 | 672 | // Set OCCT state uniform variables |
deb02f86 | 673 | aCtx->ShaderManager()->RevertClippingState(); |
4269bd1b | 674 | } |
675 | ||
825aa485 | 676 | // Restore local transformation |
6bd94e0d | 677 | aCtx->ModelWorldState.Pop(); |
678 | aCtx->SetGlNormalizeEnabled (anOldGlNormalize); | |
778cd667 | 679 | if (!myTrsfPers.IsNull()) |
825aa485 | 680 | { |
825aa485 | 681 | aCtx->WorldViewState.Pop(); |
825aa485 | 682 | } |
c827ea3a | 683 | |
2166f0fa | 684 | // Restore aspects |
f9ba5c4d | 685 | theWorkspace->SetAspectLine (aPrevAspectLine); |
686 | theWorkspace->SetAspectFace (aPrevAspectFace); | |
687 | theWorkspace->SetAspectMarker (aPrevAspectMarker); | |
688 | theWorkspace->SetAspectText (aPrevAspectText); | |
2166f0fa | 689 | |
b7cd4ba7 | 690 | // Apply highlight box |
691 | if (!myHighlightBox.IsNull()) | |
692 | { | |
f838dac4 | 693 | theWorkspace->SetHighlightStyle (myHighlightStyle); |
7d9e854b | 694 | myHighlightBox->Render (theWorkspace); |
b7cd4ba7 | 695 | } |
696 | ||
2166f0fa | 697 | // Restore named status |
f838dac4 | 698 | theWorkspace->SetHighlightStyle (Handle(Graphic3d_PresentationAttributes)()); |
2166f0fa SK |
699 | } |
700 | ||
5e27df78 | 701 | // ======================================================================= |
702 | // function : Release | |
703 | // purpose : | |
704 | // ======================================================================= | |
705 | void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx) | |
706 | { | |
707 | // Release groups | |
708 | Clear (theGlCtx); | |
8e5fb5ea | 709 | clearHighlightBox (theGlCtx); |
710 | myHighlightStyle.Nullify(); | |
5e27df78 | 711 | } |
712 | ||
dd8a4ce9 | 713 | // ======================================================================= |
714 | // function : ReleaseGlResources | |
715 | // purpose : | |
716 | // ======================================================================= | |
717 | void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx) | |
718 | { | |
b64d84be | 719 | for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) |
dd8a4ce9 | 720 | { |
b64d84be | 721 | aGroupIter.ChangeValue()->Release (theGlCtx); |
dd8a4ce9 | 722 | } |
b64d84be | 723 | if (!myHighlightBox.IsNull()) |
dd8a4ce9 | 724 | { |
10b9c7df | 725 | myHighlightBox->Release (theGlCtx.operator->()); |
dd8a4ce9 | 726 | } |
727 | } | |
728 | ||
679ecdee | 729 | //======================================================================= |
730 | //function : ShadowLink | |
731 | //purpose : | |
732 | //======================================================================= | |
733 | Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const | |
734 | { | |
735 | return new OpenGl_StructureShadow (theManager, this); | |
736 | } |