Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-08-05 |
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 | // |
973c2be1 | 7 | // This library is free software; you can redistribute it and / or modify it |
8 | // under the terms of the GNU Lesser General Public version 2.1 as published | |
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. | |
2166f0fa | 15 | |
5f8b738e | 16 | #include <OpenGl_GlCore11.hxx> |
17 | ||
2166f0fa SK |
18 | #include <OpenGl_Workspace.hxx> |
19 | ||
20 | #include <OpenGl_AspectLine.hxx> | |
21 | #include <OpenGl_AspectFace.hxx> | |
22 | #include <OpenGl_AspectMarker.hxx> | |
23 | #include <OpenGl_AspectText.hxx> | |
30f0ad28 | 24 | #include <OpenGl_Context.hxx> |
25 | #include <OpenGl_ShaderManager.hxx> | |
0f8c0fb8 | 26 | #include <OpenGl_telem_util.hxx> |
2166f0fa | 27 | |
498ce577 | 28 | #ifdef HAVE_CONFIG_H |
29 | # include <config.h> | |
30 | #endif | |
31 | ||
2166f0fa SK |
32 | /* OCC22218 NOTE: project dependency on gl2ps is specified by macro */ |
33 | #ifdef HAVE_GL2PS | |
34 | #include <gl2ps.h> | |
bf75be98 | 35 | /* OCC22216 NOTE: linker dependency can be switched off by undefining macro. |
36 | Pragma comment for gl2ps.lib is defined only here. */ | |
37 | #ifdef _MSC_VER | |
2166f0fa SK |
38 | #pragma comment( lib, "gl2ps.lib" ) |
39 | #endif | |
40 | #endif | |
41 | ||
2166f0fa | 42 | #include <Aspect_PolygonOffsetMode.hxx> |
2166f0fa SK |
43 | #include <OpenGl_View.hxx> |
44 | ||
45 | /*----------------------------------------------------------------------*/ | |
46 | ||
47 | static void TelUpdatePolygonOffsets( const TEL_POFFSET_PARAM *pdata ) | |
48 | { | |
49 | if ( ( pdata->mode & Aspect_POM_Fill ) == Aspect_POM_Fill ) | |
50 | glEnable ( GL_POLYGON_OFFSET_FILL ); | |
bf75be98 | 51 | else |
2166f0fa SK |
52 | glDisable ( GL_POLYGON_OFFSET_FILL ); |
53 | ||
54 | if ( ( pdata->mode & Aspect_POM_Line ) == Aspect_POM_Line ) | |
55 | glEnable ( GL_POLYGON_OFFSET_LINE ); | |
56 | else | |
57 | glDisable( GL_POLYGON_OFFSET_LINE ); | |
58 | ||
59 | if ( ( pdata->mode & Aspect_POM_Point ) == Aspect_POM_Point ) | |
60 | glEnable ( GL_POLYGON_OFFSET_POINT ); | |
61 | else | |
62 | glDisable( GL_POLYGON_OFFSET_POINT ); | |
63 | ||
64 | glPolygonOffset( pdata->factor, pdata->units ); | |
65 | } | |
66 | ||
67 | /*----------------------------------------------------------------------*/ | |
68 | ||
0adbd30f | 69 | void OpenGl_Workspace::updateMaterial (const int theFlag) |
2166f0fa | 70 | { |
fd4a6963 | 71 | // Case of hidden line |
72 | if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE) | |
2166f0fa | 73 | { |
fd4a6963 | 74 | myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect |
75 | myAspectFaceHl.ChangeIntFront().matcol = BackgroundColor(); | |
76 | myAspectFaceHl.ChangeIntFront().color_mask = 0; | |
77 | myAspectFaceHl.ChangeIntFront().color_mask = 0; | |
2166f0fa | 78 | |
fd4a6963 | 79 | AspectFace_set = &myAspectFaceHl; |
2166f0fa SK |
80 | return; |
81 | } | |
82 | ||
0adbd30f | 83 | const OPENGL_SURF_PROP* aProps = &AspectFace_set->IntFront(); |
84 | GLenum aFace = GL_FRONT_AND_BACK; | |
85 | if (theFlag == TEL_BACK_MATERIAL) | |
2166f0fa | 86 | { |
0adbd30f | 87 | aFace = GL_BACK; |
88 | aProps = &AspectFace_set->IntBack(); | |
2166f0fa | 89 | } |
0adbd30f | 90 | else if (AspectFace_set->DistinguishingMode() == TOn |
91 | && !(NamedStatus & OPENGL_NS_RESMAT)) | |
2166f0fa | 92 | { |
0adbd30f | 93 | aFace = GL_FRONT; |
2166f0fa SK |
94 | } |
95 | ||
0adbd30f | 96 | myMatTmp.Init (*aProps); |
97 | ||
98 | // handling transparency | |
99 | if (NamedStatus & OPENGL_NS_2NDPASSDO) | |
100 | { | |
101 | // second pass | |
102 | myMatTmp.Diffuse.a() = aProps->env_reflexion; | |
103 | } | |
104 | else | |
2166f0fa | 105 | { |
0adbd30f | 106 | if (aProps->env_reflexion != 0.0f) |
107 | { | |
108 | // if the material reflects the environment scene, the second pass is needed | |
109 | NamedStatus |= OPENGL_NS_2NDPASSNEED; | |
110 | } | |
111 | ||
112 | if (myUseTransparency && aProps->trans != 1.0f) | |
2166f0fa | 113 | { |
0adbd30f | 114 | // render transparent |
115 | myMatTmp.Diffuse.a() = aProps->trans; | |
bf75be98 | 116 | glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
0adbd30f | 117 | glEnable (GL_BLEND); |
2166f0fa SK |
118 | glDepthMask (GL_FALSE); |
119 | } | |
bf75be98 | 120 | else |
2166f0fa | 121 | { |
0adbd30f | 122 | // render opaque |
123 | if ((NamedStatus & OPENGL_NS_ANTIALIASING) == 0) | |
2166f0fa SK |
124 | { |
125 | glBlendFunc (GL_ONE, GL_ZERO); | |
0adbd30f | 126 | glDisable (GL_BLEND); |
2166f0fa SK |
127 | } |
128 | glDepthMask (GL_TRUE); | |
bf75be98 | 129 | } |
2166f0fa SK |
130 | } |
131 | ||
0adbd30f | 132 | // do not update material properties in case of zero reflection mode, |
133 | // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway. | |
134 | if (aProps->color_mask == 0) | |
bf75be98 | 135 | { |
0adbd30f | 136 | return; |
bf75be98 | 137 | } |
2166f0fa | 138 | |
0adbd30f | 139 | // reset material |
140 | if (NamedStatus & OPENGL_NS_RESMAT) | |
2166f0fa | 141 | { |
0adbd30f | 142 | glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData()); |
143 | glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData()); | |
144 | glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData()); | |
145 | glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData()); | |
146 | glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine()); | |
2166f0fa | 147 | |
0adbd30f | 148 | if (theFlag == TEL_FRONT_MATERIAL) |
2166f0fa | 149 | { |
0adbd30f | 150 | myMatFront = myMatTmp; |
151 | myMatBack = myMatTmp; | |
2166f0fa SK |
152 | } |
153 | else | |
154 | { | |
0adbd30f | 155 | myMatBack = myMatTmp; |
2166f0fa SK |
156 | } |
157 | ||
0adbd30f | 158 | NamedStatus &= ~OPENGL_NS_RESMAT; |
159 | return; | |
160 | } | |
2166f0fa | 161 | |
0adbd30f | 162 | // reduce updates |
163 | OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL) | |
164 | ? myMatFront | |
165 | : myMatBack; | |
2166f0fa | 166 | |
0adbd30f | 167 | if (myMatTmp.Ambient.r() != anOld.Ambient.r() |
168 | || myMatTmp.Ambient.g() != anOld.Ambient.g() | |
169 | || myMatTmp.Ambient.b() != anOld.Ambient.b()) | |
170 | { | |
171 | glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData()); | |
172 | } | |
173 | if (myMatTmp.Diffuse.r() != anOld.Diffuse.r() | |
174 | || myMatTmp.Diffuse.g() != anOld.Diffuse.g() | |
175 | || myMatTmp.Diffuse.b() != anOld.Diffuse.b() | |
176 | || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f) | |
177 | { | |
178 | glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData()); | |
179 | } | |
180 | if (myMatTmp.Specular.r() != anOld.Specular.r() | |
181 | || myMatTmp.Specular.g() != anOld.Specular.g() | |
182 | || myMatTmp.Specular.b() != anOld.Specular.b()) | |
183 | { | |
184 | glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData()); | |
185 | } | |
186 | if (myMatTmp.Emission.r() != anOld.Emission.r() | |
187 | || myMatTmp.Emission.g() != anOld.Emission.g() | |
188 | || myMatTmp.Emission.b() != anOld.Emission.b()) | |
189 | { | |
190 | glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData()); | |
191 | } | |
192 | if (myMatTmp.Shine() != anOld.Shine()) | |
193 | { | |
194 | glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine()); | |
195 | } | |
196 | anOld = myMatTmp; | |
197 | if (aFace == GL_FRONT_AND_BACK) | |
198 | { | |
199 | myMatBack = myMatTmp; | |
2166f0fa SK |
200 | } |
201 | } | |
202 | ||
203 | /*----------------------------------------------------------------------*/ | |
204 | ||
205 | const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect) | |
206 | { | |
207 | const OpenGl_AspectLine *AspectLine_old = AspectLine_set; | |
208 | AspectLine_set = AnAspect; | |
209 | return AspectLine_old; | |
210 | } | |
211 | ||
212 | /*----------------------------------------------------------------------*/ | |
213 | ||
214 | const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect) | |
215 | { | |
216 | const OpenGl_AspectFace *AspectFace_old = AspectFace_set; | |
217 | AspectFace_set = AnAspect; | |
218 | return AspectFace_old; | |
219 | } | |
220 | ||
221 | /*----------------------------------------------------------------------*/ | |
222 | ||
223 | const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect) | |
224 | { | |
225 | const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set; | |
226 | AspectMarker_set = AnAspect; | |
227 | return AspectMarker_old; | |
228 | } | |
229 | ||
230 | /*----------------------------------------------------------------------*/ | |
231 | ||
232 | const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect) | |
233 | { | |
234 | const OpenGl_AspectText *AspectText_old = AspectText_set; | |
235 | AspectText_set = AnAspect; | |
236 | return AspectText_old; | |
237 | } | |
238 | ||
239 | /*----------------------------------------------------------------------*/ | |
240 | ||
0f8c0fb8 | 241 | const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix (const OpenGl_Matrix *AMatrix) |
2166f0fa SK |
242 | { |
243 | const OpenGl_Matrix *ViewMatrix_old = ViewMatrix_applied; | |
244 | ViewMatrix_applied = AMatrix; | |
245 | ||
0f8c0fb8 | 246 | // Update model-view matrix with new view matrix |
247 | UpdateModelViewMatrix(); | |
2166f0fa SK |
248 | |
249 | return ViewMatrix_old; | |
250 | } | |
251 | ||
252 | /*----------------------------------------------------------------------*/ | |
253 | ||
30f0ad28 | 254 | const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix (const OpenGl_Matrix *AMatrix, bool aRevert) |
2166f0fa SK |
255 | { |
256 | const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied; | |
257 | StructureMatrix_applied = AMatrix; | |
258 | ||
259 | OpenGl_Matrix lmat; | |
260 | OpenGl_Transposemat3( &lmat, AMatrix ); | |
261 | ||
0f8c0fb8 | 262 | // Update model-view matrix with new structure matrix |
263 | UpdateModelViewMatrix(); | |
2166f0fa | 264 | |
30f0ad28 | 265 | if (!myGlContext->ShaderManager()->IsEmpty()) |
266 | { | |
267 | if (aRevert) | |
392ac980 | 268 | { |
b5ac8292 | 269 | myGlContext->ShaderManager()->RevertModelWorldStateTo (&lmat.mat); |
392ac980 | 270 | } |
271 | else | |
272 | { | |
b5ac8292 | 273 | myGlContext->ShaderManager()->UpdateModelWorldStateTo (&lmat.mat); |
392ac980 | 274 | } |
30f0ad28 | 275 | } |
276 | ||
2166f0fa SK |
277 | return StructureMatrix_old; |
278 | } | |
279 | ||
280 | /*----------------------------------------------------------------------*/ | |
281 | ||
0f8c0fb8 | 282 | const void OpenGl_Workspace::UpdateModelViewMatrix() |
283 | { | |
284 | OpenGl_Matrix aStructureMatT; | |
285 | OpenGl_Transposemat3( &aStructureMatT, StructureMatrix_applied); | |
286 | ||
287 | glMatrixMode (GL_MODELVIEW); | |
288 | OpenGl_Multiplymat3 (&myModelViewMatrix, &aStructureMatT, ViewMatrix_applied); | |
289 | glLoadMatrixf ((const GLfloat* )&myModelViewMatrix.mat); | |
290 | } | |
291 | ||
292 | /*----------------------------------------------------------------------*/ | |
293 | ||
2166f0fa SK |
294 | const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply) |
295 | { | |
296 | if ( WithApply && (AspectLine_set != AspectLine_applied) ) | |
297 | { | |
298 | glColor3fv(AspectLine_set->Color().rgb); | |
299 | ||
300 | if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) ) | |
301 | { | |
302 | myDisplay->SetTypeOfLine(AspectLine_set->Type()); | |
303 | } | |
304 | ||
305 | if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) ) | |
306 | { | |
307 | glLineWidth( (GLfloat)AspectLine_set->Width() ); | |
308 | #ifdef HAVE_GL2PS | |
309 | gl2psLineWidth( (GLfloat)AspectLine_set->Width() ); | |
310 | #endif | |
311 | } | |
312 | ||
313 | AspectLine_applied = AspectLine_set; | |
314 | } | |
315 | return AspectLine_set; | |
316 | } | |
317 | ||
318 | /*----------------------------------------------------------------------*/ | |
319 | ||
bf75be98 | 320 | const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply) |
2166f0fa | 321 | { |
3b1817a9 | 322 | if (!theToApply) |
323 | { | |
324 | return AspectFace_set; | |
325 | } | |
326 | ||
327 | if (!ActiveView()->Backfacing()) | |
328 | { | |
329 | // manage back face culling mode, disable culling when clipping is enabled | |
330 | TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn() | |
331 | || AspectFace_set->InteriorStyle() == Aspect_IS_HATCH) | |
332 | ? TelCullNone | |
333 | : (TelCullMode )AspectFace_set->CullingMode(); | |
334 | if (aCullingMode != TelCullNone | |
335 | && myUseTransparency && !(NamedStatus & OPENGL_NS_2NDPASSDO)) | |
336 | { | |
337 | // disable culling in case of translucent shading aspect | |
338 | if (AspectFace_set->IntFront().trans != 1.0f) | |
339 | { | |
340 | aCullingMode = TelCullNone; | |
341 | } | |
342 | } | |
343 | if (myCullingMode != aCullingMode) | |
344 | { | |
345 | myCullingMode = aCullingMode; | |
346 | switch (myCullingMode) | |
347 | { | |
348 | case TelCullNone: | |
349 | case TelCullUndefined: | |
350 | { | |
351 | glDisable (GL_CULL_FACE); | |
352 | break; | |
353 | } | |
354 | case TelCullFront: | |
355 | { | |
356 | glCullFace (GL_FRONT); | |
357 | glEnable (GL_CULL_FACE); | |
358 | break; | |
359 | } | |
360 | case TelCullBack: | |
361 | { | |
362 | glCullFace (GL_BACK); | |
363 | glEnable (GL_CULL_FACE); | |
364 | break; | |
365 | } | |
366 | } | |
367 | } | |
368 | } | |
369 | ||
370 | if (AspectFace_set == AspectFace_applied) | |
bf75be98 | 371 | { |
372 | return AspectFace_set; | |
373 | } | |
374 | ||
fd4a6963 | 375 | const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle(); |
376 | if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle) | |
2166f0fa | 377 | { |
bf75be98 | 378 | switch (anIntstyle) |
2166f0fa | 379 | { |
bf75be98 | 380 | case Aspect_IS_EMPTY: |
381 | case Aspect_IS_HOLLOW: | |
2166f0fa | 382 | { |
bf75be98 | 383 | glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); |
384 | break; | |
2166f0fa | 385 | } |
bf75be98 | 386 | case Aspect_IS_HATCH: |
387 | { | |
388 | glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); | |
fd4a6963 | 389 | myDisplay->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID); |
bf75be98 | 390 | break; |
391 | } | |
392 | case Aspect_IS_SOLID: | |
393 | case Aspect_IS_HIDDENLINE: | |
394 | { | |
395 | glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); | |
396 | glDisable (GL_POLYGON_STIPPLE); | |
397 | break; | |
398 | } | |
0adbd30f | 399 | case Aspect_IS_POINT: |
2166f0fa | 400 | { |
0adbd30f | 401 | glPolygonMode (GL_FRONT_AND_BACK, GL_POINT); |
bf75be98 | 402 | break; |
2166f0fa SK |
403 | } |
404 | } | |
bf75be98 | 405 | } |
406 | ||
407 | if (anIntstyle == Aspect_IS_HATCH) | |
408 | { | |
fd4a6963 | 409 | const Tint hatchstyle = AspectFace_set->Hatch(); |
410 | if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle) | |
bf75be98 | 411 | { |
412 | myDisplay->SetTypeOfHatch(hatchstyle); | |
413 | } | |
414 | } | |
415 | ||
bf75be98 | 416 | // Aspect_POM_None means: do not change current settings |
fd4a6963 | 417 | if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None) |
bf75be98 | 418 | { |
419 | if (PolygonOffset_applied == NULL | |
fd4a6963 | 420 | || PolygonOffset_applied->mode != AspectFace_set->PolygonOffset().mode |
421 | || PolygonOffset_applied->factor != AspectFace_set->PolygonOffset().factor | |
422 | || PolygonOffset_applied->units != AspectFace_set->PolygonOffset().units) | |
2166f0fa | 423 | { |
fd4a6963 | 424 | PolygonOffset_applied = &AspectFace_set->PolygonOffset(); |
bf75be98 | 425 | TelUpdatePolygonOffsets (PolygonOffset_applied); |
2166f0fa | 426 | } |
bf75be98 | 427 | } |
2166f0fa | 428 | |
0adbd30f | 429 | updateMaterial (TEL_FRONT_MATERIAL); |
fd4a6963 | 430 | if (AspectFace_set->DistinguishingMode() == TOn) |
bf75be98 | 431 | { |
0adbd30f | 432 | updateMaterial (TEL_BACK_MATERIAL); |
bf75be98 | 433 | } |
2166f0fa | 434 | |
bf75be98 | 435 | if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0) |
436 | { | |
fd4a6963 | 437 | if (AspectFace_set->DoTextureMap()) |
bf75be98 | 438 | { |
fd4a6963 | 439 | EnableTexture (AspectFace_set->TextureRes (this), |
440 | AspectFace_set->TextureParams()); | |
bf75be98 | 441 | } |
442 | else | |
2166f0fa SK |
443 | { |
444 | DisableTexture(); | |
2166f0fa | 445 | } |
2166f0fa | 446 | } |
bf75be98 | 447 | |
448 | AspectFace_applied = AspectFace_set; | |
2166f0fa SK |
449 | return AspectFace_set; |
450 | } | |
451 | ||
452 | /*----------------------------------------------------------------------*/ | |
453 | ||
17f65eb2 | 454 | const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply) |
2166f0fa | 455 | { |
17f65eb2 | 456 | if (theToApply && (AspectMarker_set != AspectMarker_applied)) |
2166f0fa | 457 | { |
17f65eb2 | 458 | if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale())) |
459 | { | |
460 | glPointSize (AspectMarker_set->Scale()); | |
461 | #ifdef HAVE_GL2PS | |
462 | gl2psPointSize (AspectMarker_set->Scale()); | |
463 | #endif | |
464 | } | |
2166f0fa SK |
465 | AspectMarker_applied = AspectMarker_set; |
466 | } | |
467 | return AspectMarker_set; | |
468 | } | |
469 | ||
470 | /*----------------------------------------------------------------------*/ | |
471 | ||
a174a3c5 | 472 | const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply) |
2166f0fa | 473 | { |
a174a3c5 | 474 | if (theWithApply) |
2166f0fa | 475 | { |
a174a3c5 | 476 | AspectText_applied = AspectText_set; |
477 | TextParam_applied = TextParam_set; | |
2166f0fa | 478 | } |
a174a3c5 | 479 | |
2166f0fa SK |
480 | return AspectText_set; |
481 | } |