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