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