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 | |
b7cd4ba7 | 39 | OpenGl_BndBoxPrs (const Graphic3d_BndBox4f& theBndBox) |
40 | { | |
41 | const float Xm = theBndBox.CornerMin().x(); | |
42 | const float Ym = theBndBox.CornerMin().y(); | |
43 | const float Zm = theBndBox.CornerMin().z(); | |
44 | const float XM = theBndBox.CornerMax().x(); | |
45 | const float YM = theBndBox.CornerMax().y(); | |
46 | const float ZM = theBndBox.CornerMax().z(); | |
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 | ||
73 | glDisable (GL_LIGHTING); | |
27eed937 | 74 | |
75 | // Use highlight colors | |
b6472664 | 76 | theWorkspace->GetGlContext()->core11->glColor3fv (theWorkspace->LineColor().GetData()); |
27eed937 | 77 | |
78 | glEnableClientState (GL_VERTEX_ARRAY); | |
79 | glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts); | |
80 | glDrawArrays (GL_LINE_STRIP, 0, 16); | |
81 | glDisableClientState (GL_VERTEX_ARRAY); | |
82 | ||
83 | // restore aspects | |
84 | if (!aPrevTexture.IsNull()) | |
85 | { | |
86 | theWorkspace->EnableTexture (aPrevTexture); | |
87 | } | |
20aeeb7b | 88 | #else |
89 | (void )theWorkspace; | |
ca3c13d1 | 90 | #endif |
27eed937 | 91 | } |
92 | ||
93 | //! Release graphical resources | |
10b9c7df | 94 | virtual void Release (OpenGl_Context*) |
27eed937 | 95 | { |
96 | // | |
97 | } | |
98 | ||
99 | protected: | |
100 | ||
101 | //! Protected destructor | |
102 | virtual ~OpenGl_BndBoxPrs() {} | |
103 | ||
104 | private: | |
105 | ||
106 | OpenGl_Vec3 myVerts[16]; //!< vertices array | |
107 | ||
108 | public: | |
109 | ||
110 | DEFINE_STANDARD_ALLOC | |
111 | ||
112 | }; | |
2166f0fa SK |
113 | |
114 | /*----------------------------------------------------------------------*/ | |
115 | ||
4269bd1b | 116 | // ======================================================================= |
117 | // function : OpenGl_Structure | |
118 | // purpose : | |
119 | // ======================================================================= | |
63bcc448 | 120 | OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager) |
121 | : Graphic3d_CStructure (theManager), | |
d4aaad5b | 122 | myHighlightColor (NULL), |
123 | myInstancedStructure (NULL), | |
124 | myIsRaytracable (Standard_False), | |
125 | myModificationState (0), | |
126 | myIsCulled (Standard_True), | |
127 | myIsMirrored (Standard_False) | |
2166f0fa | 128 | { |
a1954302 | 129 | // |
2166f0fa SK |
130 | } |
131 | ||
4269bd1b | 132 | // ======================================================================= |
133 | // function : ~OpenGl_Structure | |
134 | // purpose : | |
135 | // ======================================================================= | |
5e27df78 | 136 | OpenGl_Structure::~OpenGl_Structure() |
2166f0fa | 137 | { |
5e27df78 | 138 | Release (Handle(OpenGl_Context)()); |
2166f0fa SK |
139 | } |
140 | ||
63bcc448 | 141 | // ======================================================================= |
142 | // function : UpdateTransformation | |
143 | // purpose : | |
144 | // ======================================================================= | |
145 | void OpenGl_Structure::UpdateTransformation() | |
146 | { | |
6bd94e0d | 147 | const OpenGl_Mat4& aMat = Graphic3d_CStructure::Transformation; |
7d9e854b | 148 | Standard_ShortReal aDet = |
6bd94e0d | 149 | aMat.GetValue(0, 0) * (aMat.GetValue(1, 1) * aMat.GetValue(2, 2) - aMat.GetValue(2, 1) * aMat.GetValue(1, 2)) - |
150 | aMat.GetValue(0, 1) * (aMat.GetValue(1, 0) * aMat.GetValue(2, 2) - aMat.GetValue(2, 0) * aMat.GetValue(1, 2)) + | |
151 | aMat.GetValue(0, 2) * (aMat.GetValue(1, 0) * aMat.GetValue(2, 1) - aMat.GetValue(2, 0) * aMat.GetValue(1, 1)); | |
7d9e854b | 152 | |
153 | // Determinant of transform matrix less then 0 means that mirror transform applied. | |
154 | myIsMirrored = aDet < 0.0f; | |
155 | ||
d4aaad5b | 156 | if (IsRaytracable()) |
e276548b | 157 | { |
d4aaad5b | 158 | ++myModificationState; |
e276548b | 159 | } |
2166f0fa SK |
160 | } |
161 | ||
4269bd1b | 162 | // ======================================================================= |
b64d84be | 163 | // function : clearHighlightBox |
4269bd1b | 164 | // purpose : |
165 | // ======================================================================= | |
b64d84be | 166 | void OpenGl_Structure::clearHighlightBox (const Handle(OpenGl_Context)& theGlCtx) |
2166f0fa | 167 | { |
b64d84be | 168 | if (!myHighlightBox.IsNull()) |
5e27df78 | 169 | { |
170 | myHighlightBox->Release (theGlCtx); | |
b64d84be | 171 | myHighlightBox.Nullify(); |
2166f0fa SK |
172 | } |
173 | } | |
174 | ||
63bcc448 | 175 | // ======================================================================= |
176 | // function : HighlightWithColor | |
177 | // purpose : | |
178 | // ======================================================================= | |
179 | void OpenGl_Structure::HighlightWithColor (const Graphic3d_Vec3& theColor, | |
180 | const Standard_Boolean theToCreate) | |
181 | { | |
7d9e854b | 182 | const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext(); |
63bcc448 | 183 | if (theToCreate) |
7d9e854b | 184 | setHighlightColor (aContext, theColor); |
63bcc448 | 185 | else |
7d9e854b | 186 | clearHighlightColor (aContext); |
63bcc448 | 187 | } |
188 | ||
189 | // ======================================================================= | |
190 | // function : HighlightWithBndBox | |
191 | // purpose : | |
192 | // ======================================================================= | |
b64d84be | 193 | void OpenGl_Structure::HighlightWithBndBox (const Handle(Graphic3d_Structure)& theStruct, |
194 | const Standard_Boolean theToCreate) | |
63bcc448 | 195 | { |
7d9e854b | 196 | const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext(); |
b64d84be | 197 | if (!theToCreate) |
198 | { | |
7d9e854b | 199 | clearHighlightBox (aContext); |
b64d84be | 200 | return; |
201 | } | |
202 | ||
203 | if (!myHighlightBox.IsNull()) | |
204 | { | |
7d9e854b | 205 | myHighlightBox->Release (aContext); |
b64d84be | 206 | } |
63bcc448 | 207 | else |
b64d84be | 208 | { |
209 | myHighlightBox = new OpenGl_Group (theStruct); | |
210 | } | |
211 | ||
b6472664 | 212 | myHighlightBox->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (HighlightColor, Aspect_TOL_SOLID, 1.0)); |
b64d84be | 213 | |
b7cd4ba7 | 214 | OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox); |
b64d84be | 215 | myHighlightBox->AddElement (aBndBoxPrs); |
63bcc448 | 216 | } |
217 | ||
4269bd1b | 218 | // ======================================================================= |
b64d84be | 219 | // function : setHighlightColor |
4269bd1b | 220 | // purpose : |
221 | // ======================================================================= | |
b64d84be | 222 | void OpenGl_Structure::setHighlightColor (const Handle(OpenGl_Context)& theGlCtx, |
63bcc448 | 223 | const Graphic3d_Vec3& theColor) |
2166f0fa | 224 | { |
b64d84be | 225 | clearHighlightBox (theGlCtx); |
5e27df78 | 226 | if (myHighlightColor == NULL) |
227 | { | |
b6472664 | 228 | myHighlightColor = new OpenGl_Vec4 (theColor, 1.0f); |
229 | } | |
230 | else | |
231 | { | |
232 | myHighlightColor->xyz() = theColor; | |
5e27df78 | 233 | } |
2166f0fa SK |
234 | } |
235 | ||
4269bd1b | 236 | // ======================================================================= |
b64d84be | 237 | // function : clearHighlightColor |
4269bd1b | 238 | // purpose : |
239 | // ======================================================================= | |
b64d84be | 240 | void OpenGl_Structure::clearHighlightColor (const Handle(OpenGl_Context)& theGlCtx) |
2166f0fa | 241 | { |
b64d84be | 242 | clearHighlightBox(theGlCtx); |
5e27df78 | 243 | delete myHighlightColor; |
244 | myHighlightColor = NULL; | |
2166f0fa SK |
245 | } |
246 | ||
e276548b | 247 | // ======================================================================= |
a1954302 | 248 | // function : OnVisibilityChanged |
e276548b | 249 | // purpose : |
250 | // ======================================================================= | |
a1954302 | 251 | void OpenGl_Structure::OnVisibilityChanged() |
e276548b | 252 | { |
d4aaad5b | 253 | if (IsRaytracable()) |
e276548b | 254 | { |
d4aaad5b | 255 | ++myModificationState; |
e276548b | 256 | } |
e276548b | 257 | } |
258 | ||
e276548b | 259 | // ======================================================================= |
d4aaad5b | 260 | // function : IsRaytracable |
e276548b | 261 | // purpose : |
262 | // ======================================================================= | |
d4aaad5b | 263 | Standard_Boolean OpenGl_Structure::IsRaytracable() const |
e276548b | 264 | { |
3e05329c | 265 | if (!myGroups.IsEmpty() |
266 | && myIsRaytracable) | |
e276548b | 267 | { |
3e05329c | 268 | return Standard_True; |
e276548b | 269 | } |
d5af8626 | 270 | |
3e05329c | 271 | return myInstancedStructure != NULL |
272 | && myInstancedStructure->IsRaytracable(); | |
d5af8626 | 273 | } |
274 | ||
e276548b | 275 | // ======================================================================= |
d4aaad5b | 276 | // function : UpdateRaytracableState |
e276548b | 277 | // purpose : |
278 | // ======================================================================= | |
d4aaad5b | 279 | void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const |
e276548b | 280 | { |
3e05329c | 281 | myIsRaytracable = !toCheck; |
282 | if (!myIsRaytracable) | |
283 | { | |
284 | for (OpenGl_Structure::GroupIterator anIter (myGroups); anIter.More(); anIter.Next()) | |
285 | { | |
286 | if (anIter.Value()->IsRaytracable()) | |
287 | { | |
288 | myIsRaytracable = Standard_True; | |
289 | break; | |
290 | } | |
291 | } | |
292 | } | |
e276548b | 293 | |
d4aaad5b | 294 | if (IsRaytracable()) |
e276548b | 295 | { |
d4aaad5b | 296 | ++myModificationState; |
e276548b | 297 | } |
298 | } | |
299 | ||
4269bd1b | 300 | // ======================================================================= |
301 | // function : Connect | |
302 | // purpose : | |
303 | // ======================================================================= | |
63bcc448 | 304 | void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure) |
2166f0fa | 305 | { |
d4aaad5b | 306 | OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure); |
307 | ||
308 | Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct, | |
309 | "Error! Instanced structure is already defined"); | |
310 | ||
311 | myInstancedStructure = aStruct; | |
e276548b | 312 | |
63bcc448 | 313 | if (aStruct->IsRaytracable()) |
e276548b | 314 | { |
d4aaad5b | 315 | UpdateStateIfRaytracable (Standard_False); |
e276548b | 316 | } |
2166f0fa SK |
317 | } |
318 | ||
4269bd1b | 319 | // ======================================================================= |
320 | // function : Disconnect | |
321 | // purpose : | |
322 | // ======================================================================= | |
63bcc448 | 323 | void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure) |
2166f0fa | 324 | { |
d4aaad5b | 325 | OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure); |
e276548b | 326 | |
d4aaad5b | 327 | if (myInstancedStructure == aStruct) |
328 | { | |
329 | myInstancedStructure = NULL; | |
e276548b | 330 | |
d4aaad5b | 331 | if (aStruct->IsRaytracable()) |
332 | { | |
333 | UpdateStateIfRaytracable(); | |
2166f0fa | 334 | } |
2166f0fa SK |
335 | } |
336 | } | |
337 | ||
4269bd1b | 338 | // ======================================================================= |
b64d84be | 339 | // function : NewGroup |
4269bd1b | 340 | // purpose : |
341 | // ======================================================================= | |
b64d84be | 342 | Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Structure)& theStruct) |
2166f0fa | 343 | { |
b64d84be | 344 | Handle(OpenGl_Group) aGroup = new OpenGl_Group (theStruct); |
345 | myGroups.Append (aGroup); | |
346 | return aGroup; | |
2166f0fa SK |
347 | } |
348 | ||
4269bd1b | 349 | // ======================================================================= |
350 | // function : RemoveGroup | |
351 | // purpose : | |
352 | // ======================================================================= | |
b64d84be | 353 | void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup) |
2166f0fa | 354 | { |
b64d84be | 355 | if (theGroup.IsNull()) |
356 | { | |
357 | return; | |
358 | } | |
359 | ||
360 | for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) | |
2166f0fa SK |
361 | { |
362 | // Check for the given group | |
b64d84be | 363 | if (aGroupIter.Value() == theGroup) |
2166f0fa | 364 | { |
d4aaad5b | 365 | const Standard_Boolean wasRaytracable = |
366 | static_cast<const OpenGl_Group&> (*theGroup).IsRaytracable(); | |
367 | ||
b64d84be | 368 | theGroup->Clear (Standard_False); |
e276548b | 369 | |
d4aaad5b | 370 | if (wasRaytracable) |
e276548b | 371 | { |
d4aaad5b | 372 | UpdateStateIfRaytracable(); |
e276548b | 373 | } |
e276548b | 374 | |
b64d84be | 375 | myGroups.Remove (aGroupIter); |
2166f0fa SK |
376 | return; |
377 | } | |
2166f0fa SK |
378 | } |
379 | } | |
380 | ||
63bcc448 | 381 | // ======================================================================= |
382 | // function : Clear | |
383 | // purpose : | |
384 | // ======================================================================= | |
385 | void OpenGl_Structure::Clear() | |
386 | { | |
387 | Clear (GlDriver()->GetSharedContext()); | |
388 | } | |
389 | ||
4269bd1b | 390 | // ======================================================================= |
391 | // function : Clear | |
392 | // purpose : | |
393 | // ======================================================================= | |
5e27df78 | 394 | void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx) |
2166f0fa | 395 | { |
e276548b | 396 | Standard_Boolean aRaytracableGroupDeleted (Standard_False); |
e276548b | 397 | |
5e27df78 | 398 | // Release groups |
b64d84be | 399 | for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) |
2166f0fa | 400 | { |
b64d84be | 401 | aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable(); |
5322131b | 402 | |
2166f0fa | 403 | // Delete objects |
b64d84be | 404 | aGroupIter.ChangeValue()->Release (theGlCtx); |
2166f0fa SK |
405 | } |
406 | myGroups.Clear(); | |
e276548b | 407 | |
e276548b | 408 | if (aRaytracableGroupDeleted) |
409 | { | |
d4aaad5b | 410 | myIsRaytracable = Standard_False; |
e276548b | 411 | } |
b7cd4ba7 | 412 | |
413 | Is2dText = Standard_False; | |
414 | IsForHighlight = Standard_False; | |
2166f0fa SK |
415 | } |
416 | ||
0717ddc1 | 417 | // ======================================================================= |
cc6852f3 | 418 | // function : renderGeometry |
0717ddc1 | 419 | // purpose : |
420 | // ======================================================================= | |
cc6852f3 | 421 | void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace, |
422 | bool& theHasClosed) const | |
0717ddc1 | 423 | { |
cc6852f3 | 424 | if (myInstancedStructure != NULL) |
0717ddc1 | 425 | { |
cc6852f3 | 426 | myInstancedStructure->renderGeometry (theWorkspace, theHasClosed); |
427 | } | |
428 | ||
429 | for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) | |
430 | { | |
431 | theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed(); | |
7d9e854b | 432 | aGroupIter.Value()->Render (theWorkspace); |
0717ddc1 | 433 | } |
434 | } | |
cc6852f3 | 435 | |
4269bd1b | 436 | // ======================================================================= |
437 | // function : Render | |
438 | // purpose : | |
439 | // ======================================================================= | |
7d9e854b | 440 | void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) const |
2166f0fa SK |
441 | { |
442 | // Process the structure only if visible | |
a1954302 | 443 | if (!visible) |
7d9e854b | 444 | { |
2166f0fa | 445 | return; |
7d9e854b | 446 | } |
2166f0fa | 447 | |
c827ea3a | 448 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); |
b7cd4ba7 | 449 | |
2166f0fa | 450 | // Render named status |
a1954302 | 451 | if (highlight) |
452 | { | |
f9ba5c4d | 453 | theWorkspace->SetHighlight (true); |
a1954302 | 454 | } |
2166f0fa | 455 | |
2166f0fa | 456 | // Apply local transformation |
6bd94e0d | 457 | aCtx->ModelWorldState.Push(); |
458 | aCtx->ModelWorldState.SetCurrent (Transformation); | |
459 | ||
1d92133e | 460 | const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled(); |
461 | ||
462 | #if !defined(GL_ES_VERSION_2_0) | |
463 | // detect scale transform | |
464 | if (aCtx->core11 != NULL) | |
465 | { | |
466 | const Standard_ShortReal aScaleX = Transformation.GetRow (0).xyz().SquareModulus(); | |
467 | if (Abs (aScaleX - 1.f) > Precision::Confusion()) | |
468 | { | |
469 | aCtx->SetGlNormalizeEnabled (Standard_True); | |
470 | } | |
471 | } | |
472 | #endif | |
473 | ||
825aa485 | 474 | if (TransformPersistence.Flags) |
475 | { | |
476 | OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current(); | |
477 | OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current(); | |
3bffef55 | 478 | TransformPersistence.Apply (theWorkspace->View()->Camera(), aProjection, aWorldView, |
479 | aCtx->Viewport()[2], aCtx->Viewport()[3]); | |
2166f0fa | 480 | |
825aa485 | 481 | aCtx->ProjectionState.Push(); |
482 | aCtx->WorldViewState.Push(); | |
483 | aCtx->ProjectionState.SetCurrent (aProjection); | |
484 | aCtx->WorldViewState.SetCurrent (aWorldView); | |
485 | aCtx->ApplyProjectionMatrix(); | |
2166f0fa | 486 | |
1d92133e | 487 | #if !defined(GL_ES_VERSION_2_0) |
488 | if (!aCtx->IsGlNormalizeEnabled() | |
489 | && aCtx->core11 != NULL) | |
490 | { | |
491 | const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor<Standard_ShortReal> (aWorldView); | |
492 | if (Abs (aScale - 1.0f) > Precision::Confusion()) | |
493 | { | |
494 | aCtx->SetGlNormalizeEnabled (Standard_True); | |
495 | } | |
496 | } | |
497 | #endif | |
04be5003 | 498 | } |
499 | ||
d437b80d | 500 | // Take into account transform persistence |
501 | aCtx->ApplyModelViewMatrix(); | |
c827ea3a | 502 | |
f9ba5c4d | 503 | // remember aspects |
504 | const OpenGl_AspectLine* aPrevAspectLine = theWorkspace->AspectLine(); | |
505 | const OpenGl_AspectFace* aPrevAspectFace = theWorkspace->AspectFace(); | |
506 | const OpenGl_AspectMarker* aPrevAspectMarker = theWorkspace->AspectMarker(); | |
507 | const OpenGl_AspectText* aPrevAspectText = theWorkspace->AspectText(); | |
7d9e854b | 508 | |
509 | // Apply correction for mirror transform | |
510 | if (myIsMirrored) | |
511 | { | |
c827ea3a | 512 | aCtx->core11fwd->glFrontFace (GL_CW); |
7d9e854b | 513 | } |
2166f0fa | 514 | |
2166f0fa | 515 | // Apply highlight color |
b6472664 | 516 | const OpenGl_Vec4* aHighlightColor = theWorkspace->HighlightColor; |
2166f0fa | 517 | if (myHighlightColor) |
7d9e854b | 518 | theWorkspace->HighlightColor = myHighlightColor; |
2166f0fa | 519 | |
4269bd1b | 520 | // Set up plane equations for non-structure transformed global model-view matrix |
b859a34d | 521 | // List of planes to be applied to context state |
1a7ece8f | 522 | Handle(NCollection_Shared<Graphic3d_SequenceOfHClipPlane>) aUserPlanes, aDisabledPlanes; |
b859a34d | 523 | |
524 | // Collect clipping planes of structure scope | |
525 | if (!myClipPlanes.IsEmpty()) | |
4269bd1b | 526 | { |
1a7ece8f | 527 | for (Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes); aClippingIter.More(); aClippingIter.Next()) |
b859a34d | 528 | { |
7d9e854b | 529 | const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIter.Value(); |
b859a34d | 530 | if (!aClipPlane->IsOn()) |
531 | { | |
532 | continue; | |
533 | } | |
534 | ||
535 | if (aUserPlanes.IsNull()) | |
536 | { | |
1a7ece8f | 537 | aUserPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>(); |
b859a34d | 538 | } |
51b10cd4 | 539 | aUserPlanes->Append (aClipPlane); |
b859a34d | 540 | } |
4269bd1b | 541 | } |
1a7ece8f | 542 | if (!aUserPlanes.IsNull()) |
4269bd1b | 543 | { |
b859a34d | 544 | // add planes at loaded view matrix state |
79f4f036 | 545 | aCtx->ChangeClipping().AddWorld (aCtx, *aUserPlanes); |
30f0ad28 | 546 | |
547 | // Set OCCT state uniform variables | |
deb02f86 | 548 | aCtx->ShaderManager()->UpdateClippingState(); |
4269bd1b | 549 | } |
550 | ||
1a7ece8f | 551 | // True if structure is fully clipped |
552 | bool isClipped = false; | |
553 | ||
554 | // Set of clipping planes that do not intersect the structure, | |
555 | // and thus can be disabled to improve rendering performance | |
556 | const Graphic3d_BndBox4f& aBBox = BoundingBox(); | |
557 | if (!aCtx->Clipping().Planes().IsEmpty() && aBBox.IsValid() && TransformPersistence.Flags == Graphic3d_TMF_None) | |
558 | { | |
559 | for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aCtx->Clipping().Planes()); aPlaneIt.More(); aPlaneIt.Next()) | |
560 | { | |
561 | const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); | |
562 | if (!aPlane->IsOn()) | |
563 | { | |
564 | continue; | |
565 | } | |
566 | ||
567 | // check for clipping | |
568 | const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation(); | |
569 | const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(), | |
570 | aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(), | |
571 | aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(), | |
572 | 1.0); | |
573 | if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space | |
574 | { | |
575 | isClipped = true; | |
576 | break; | |
577 | } | |
578 | ||
579 | // check for no intersection (e.g. object is "entirely not clipped") | |
580 | const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(), | |
581 | aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(), | |
582 | aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(), | |
583 | 1.0); | |
584 | if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space | |
585 | { | |
586 | aCtx->ChangeClipping().SetEnabled (aCtx, aPlane, Standard_False); | |
587 | if (aDisabledPlanes.IsNull()) | |
588 | { | |
589 | aDisabledPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>(); | |
590 | if (aUserPlanes.IsNull()) | |
591 | { | |
592 | aCtx->ShaderManager()->UpdateClippingState(); | |
593 | } | |
594 | } | |
595 | aDisabledPlanes->Append (aPlane); | |
596 | } | |
597 | } | |
598 | } | |
599 | ||
2166f0fa | 600 | // Render groups |
cc6852f3 | 601 | bool hasClosedPrims = false; |
1a7ece8f | 602 | if (!isClipped) |
603 | { | |
604 | renderGeometry (theWorkspace, hasClosedPrims); | |
605 | } | |
2166f0fa | 606 | |
7d9e854b | 607 | // Reset correction for mirror transform |
608 | if (myIsMirrored) | |
c827ea3a | 609 | { |
610 | aCtx->core11fwd->glFrontFace (GL_CCW); | |
611 | } | |
7d9e854b | 612 | |
b859a34d | 613 | // Render capping for structure groups |
cc6852f3 | 614 | if (hasClosedPrims |
1a7ece8f | 615 | && aCtx->Clipping().IsCappingOn()) |
b859a34d | 616 | { |
cc6852f3 | 617 | OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this); |
b859a34d | 618 | } |
4269bd1b | 619 | |
b859a34d | 620 | // Revert structure clippings |
1a7ece8f | 621 | if (!aDisabledPlanes.IsNull()) |
622 | { | |
623 | // enable planes that were previously disabled | |
624 | for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aDisabledPlanes); aPlaneIt.More(); aPlaneIt.Next()) | |
625 | { | |
626 | aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt.Value(), Standard_True); | |
627 | } | |
628 | if (aUserPlanes.IsNull()) | |
629 | { | |
630 | aCtx->ShaderManager()->RevertClippingState(); | |
631 | } | |
632 | } | |
633 | if (!aUserPlanes.IsNull()) | |
4269bd1b | 634 | { |
79f4f036 | 635 | aCtx->ChangeClipping().Remove (aCtx, *aUserPlanes); |
30f0ad28 | 636 | |
637 | // Set OCCT state uniform variables | |
deb02f86 | 638 | aCtx->ShaderManager()->RevertClippingState(); |
4269bd1b | 639 | } |
640 | ||
825aa485 | 641 | // Restore local transformation |
6bd94e0d | 642 | aCtx->ModelWorldState.Pop(); |
643 | aCtx->SetGlNormalizeEnabled (anOldGlNormalize); | |
825aa485 | 644 | if (TransformPersistence.Flags) |
645 | { | |
646 | aCtx->ProjectionState.Pop(); | |
647 | aCtx->WorldViewState.Pop(); | |
648 | aCtx->ApplyProjectionMatrix(); | |
649 | } | |
c827ea3a | 650 | |
2166f0fa | 651 | // Restore highlight color |
7d9e854b | 652 | theWorkspace->HighlightColor = aHighlightColor; |
2166f0fa SK |
653 | |
654 | // Restore aspects | |
f9ba5c4d | 655 | theWorkspace->SetAspectLine (aPrevAspectLine); |
656 | theWorkspace->SetAspectFace (aPrevAspectFace); | |
657 | theWorkspace->SetAspectMarker (aPrevAspectMarker); | |
658 | theWorkspace->SetAspectText (aPrevAspectText); | |
2166f0fa | 659 | |
b7cd4ba7 | 660 | // Apply highlight box |
661 | if (!myHighlightBox.IsNull()) | |
662 | { | |
7d9e854b | 663 | myHighlightBox->Render (theWorkspace); |
b7cd4ba7 | 664 | } |
665 | ||
2166f0fa | 666 | // Restore named status |
f9ba5c4d | 667 | theWorkspace->SetHighlight (false); |
2166f0fa SK |
668 | } |
669 | ||
5e27df78 | 670 | // ======================================================================= |
671 | // function : Release | |
672 | // purpose : | |
673 | // ======================================================================= | |
674 | void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx) | |
675 | { | |
676 | // Release groups | |
677 | Clear (theGlCtx); | |
b64d84be | 678 | clearHighlightColor (theGlCtx); |
5e27df78 | 679 | } |
680 | ||
dd8a4ce9 | 681 | // ======================================================================= |
682 | // function : ReleaseGlResources | |
683 | // purpose : | |
684 | // ======================================================================= | |
685 | void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx) | |
686 | { | |
b64d84be | 687 | for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) |
dd8a4ce9 | 688 | { |
b64d84be | 689 | aGroupIter.ChangeValue()->Release (theGlCtx); |
dd8a4ce9 | 690 | } |
b64d84be | 691 | if (!myHighlightBox.IsNull()) |
dd8a4ce9 | 692 | { |
10b9c7df | 693 | myHighlightBox->Release (theGlCtx.operator->()); |
dd8a4ce9 | 694 | } |
695 | } | |
696 | ||
679ecdee | 697 | //======================================================================= |
698 | //function : ShadowLink | |
699 | //purpose : | |
700 | //======================================================================= | |
701 | Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const | |
702 | { | |
703 | return new OpenGl_StructureShadow (theManager, this); | |
704 | } |