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