0026128: Visualization, TKOpenGl - fix misprint in external GLX context initialization
[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
a6964ce6 122 if (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)
4e1523ef 153 if (myGlContext->core11 != NULL)
154 {
155 myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
156 myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
157 myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
158 myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
159 myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
160 }
ca3c13d1 161 #endif
2166f0fa 162
0adbd30f 163 if (theFlag == TEL_FRONT_MATERIAL)
2166f0fa 164 {
0adbd30f 165 myMatFront = myMatTmp;
166 myMatBack = myMatTmp;
2166f0fa
SK
167 }
168 else
169 {
0adbd30f 170 myMatBack = myMatTmp;
2166f0fa
SK
171 }
172
0adbd30f 173 NamedStatus &= ~OPENGL_NS_RESMAT;
174 return;
175 }
2166f0fa 176
0adbd30f 177 // reduce updates
178 OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
179 ? myMatFront
180 : myMatBack;
ca3c13d1 181#if !defined(GL_ES_VERSION_2_0)
4e1523ef 182 if (myGlContext->core11 != NULL)
0adbd30f 183 {
4e1523ef 184 if (myMatTmp.Ambient.r() != anOld.Ambient.r()
185 || myMatTmp.Ambient.g() != anOld.Ambient.g()
186 || myMatTmp.Ambient.b() != anOld.Ambient.b())
187 {
188 myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
189 }
190 if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
191 || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
192 || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
193 || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
194 {
195 myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
196 }
197 if (myMatTmp.Specular.r() != anOld.Specular.r()
198 || myMatTmp.Specular.g() != anOld.Specular.g()
199 || myMatTmp.Specular.b() != anOld.Specular.b())
200 {
201 myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
202 }
203 if (myMatTmp.Emission.r() != anOld.Emission.r()
204 || myMatTmp.Emission.g() != anOld.Emission.g()
205 || myMatTmp.Emission.b() != anOld.Emission.b())
206 {
207 myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
208 }
209 if (myMatTmp.Shine() != anOld.Shine())
210 {
211 myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
212 }
0adbd30f 213 }
ca3c13d1 214#endif
0adbd30f 215 anOld = myMatTmp;
216 if (aFace == GL_FRONT_AND_BACK)
217 {
218 myMatBack = myMatTmp;
2166f0fa
SK
219 }
220}
221
222/*----------------------------------------------------------------------*/
223
224const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
225{
226 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
227 AspectLine_set = AnAspect;
228 return AspectLine_old;
229}
230
231/*----------------------------------------------------------------------*/
232
233const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
234{
235 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
236 AspectFace_set = AnAspect;
237 return AspectFace_old;
238}
239
240/*----------------------------------------------------------------------*/
241
242const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
243{
244 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
245 AspectMarker_set = AnAspect;
246 return AspectMarker_old;
247}
248
249/*----------------------------------------------------------------------*/
250
251const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
252{
253 const OpenGl_AspectText *AspectText_old = AspectText_set;
254 AspectText_set = AnAspect;
255 return AspectText_old;
256}
257
258/*----------------------------------------------------------------------*/
259
2166f0fa
SK
260const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean WithApply)
261{
262 if ( WithApply && (AspectLine_set != AspectLine_applied) )
263 {
4e1523ef 264 myGlContext->SetColor4fv (*(const OpenGl_Vec4* )AspectLine_set->Color().rgb);
2166f0fa
SK
265 if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
266 {
73192b37 267 myLineAttribs->SetTypeOfLine (AspectLine_set->Type());
2166f0fa
SK
268 }
269
270 if ( !AspectLine_applied || ( AspectLine_set->Width() != AspectLine_applied->Width() ) )
271 {
272 glLineWidth( (GLfloat)AspectLine_set->Width() );
273#ifdef HAVE_GL2PS
274 gl2psLineWidth( (GLfloat)AspectLine_set->Width() );
275#endif
276 }
277
278 AspectLine_applied = AspectLine_set;
279 }
280 return AspectLine_set;
281}
282
283/*----------------------------------------------------------------------*/
284
bf75be98 285const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
2166f0fa 286{
3b1817a9 287 if (!theToApply)
288 {
289 return AspectFace_set;
290 }
291
292 if (!ActiveView()->Backfacing())
293 {
294 // manage back face culling mode, disable culling when clipping is enabled
295 TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn()
296 || AspectFace_set->InteriorStyle() == Aspect_IS_HATCH)
297 ? TelCullNone
298 : (TelCullMode )AspectFace_set->CullingMode();
299 if (aCullingMode != TelCullNone
a6964ce6 300 && !(NamedStatus & OPENGL_NS_2NDPASSDO))
3b1817a9 301 {
302 // disable culling in case of translucent shading aspect
303 if (AspectFace_set->IntFront().trans != 1.0f)
304 {
305 aCullingMode = TelCullNone;
306 }
307 }
308 if (myCullingMode != aCullingMode)
309 {
310 myCullingMode = aCullingMode;
311 switch (myCullingMode)
312 {
313 case TelCullNone:
314 case TelCullUndefined:
315 {
316 glDisable (GL_CULL_FACE);
317 break;
318 }
319 case TelCullFront:
320 {
321 glCullFace (GL_FRONT);
322 glEnable (GL_CULL_FACE);
323 break;
324 }
325 case TelCullBack:
326 {
327 glCullFace (GL_BACK);
328 glEnable (GL_CULL_FACE);
329 break;
330 }
331 }
332 }
333 }
334
335 if (AspectFace_set == AspectFace_applied)
bf75be98 336 {
337 return AspectFace_set;
338 }
339
ca3c13d1 340#if !defined(GL_ES_VERSION_2_0)
fd4a6963 341 const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle();
342 if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle)
2166f0fa 343 {
bf75be98 344 switch (anIntstyle)
2166f0fa 345 {
bf75be98 346 case Aspect_IS_EMPTY:
347 case Aspect_IS_HOLLOW:
2166f0fa 348 {
bf75be98 349 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
350 break;
2166f0fa 351 }
bf75be98 352 case Aspect_IS_HATCH:
353 {
354 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
73192b37 355 myLineAttribs->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID);
bf75be98 356 break;
357 }
358 case Aspect_IS_SOLID:
359 case Aspect_IS_HIDDENLINE:
360 {
361 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
4e1523ef 362 if (myGlContext->core11 != NULL)
363 {
364 glDisable (GL_POLYGON_STIPPLE);
365 }
bf75be98 366 break;
367 }
0adbd30f 368 case Aspect_IS_POINT:
2166f0fa 369 {
0adbd30f 370 glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
bf75be98 371 break;
2166f0fa
SK
372 }
373 }
bf75be98 374 }
375
376 if (anIntstyle == Aspect_IS_HATCH)
377 {
fd4a6963 378 const Tint hatchstyle = AspectFace_set->Hatch();
379 if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle)
bf75be98 380 {
73192b37 381 myLineAttribs->SetTypeOfHatch (hatchstyle);
bf75be98 382 }
383 }
ca3c13d1 384#endif
bf75be98 385
bf75be98 386 // Aspect_POM_None means: do not change current settings
fd4a6963 387 if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
bf75be98 388 {
550f3b8b 389 if (PolygonOffset_applied.mode != AspectFace_set->PolygonOffset().mode
390 || PolygonOffset_applied.factor != AspectFace_set->PolygonOffset().factor
391 || PolygonOffset_applied.units != AspectFace_set->PolygonOffset().units)
2166f0fa 392 {
550f3b8b 393 SetPolygonOffset (AspectFace_set->PolygonOffset().mode,
394 AspectFace_set->PolygonOffset().factor,
395 AspectFace_set->PolygonOffset().units);
2166f0fa 396 }
bf75be98 397 }
2166f0fa 398
0adbd30f 399 updateMaterial (TEL_FRONT_MATERIAL);
fd4a6963 400 if (AspectFace_set->DistinguishingMode() == TOn)
bf75be98 401 {
0adbd30f 402 updateMaterial (TEL_BACK_MATERIAL);
bf75be98 403 }
2166f0fa 404
bf75be98 405 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
406 {
fd4a6963 407 if (AspectFace_set->DoTextureMap())
bf75be98 408 {
8625ef7e 409 EnableTexture (AspectFace_set->TextureRes (myGlContext),
fd4a6963 410 AspectFace_set->TextureParams());
bf75be98 411 }
412 else
2166f0fa
SK
413 {
414 DisableTexture();
2166f0fa 415 }
2166f0fa 416 }
bf75be98 417
418 AspectFace_applied = AspectFace_set;
2166f0fa
SK
419 return AspectFace_set;
420}
421
550f3b8b 422//=======================================================================
423//function : SetPolygonOffset
424//purpose :
425//=======================================================================
426void OpenGl_Workspace::SetPolygonOffset (int theMode,
427 Standard_ShortReal theFactor,
428 Standard_ShortReal theUnits)
429{
430 PolygonOffset_applied.mode = theMode;
431 PolygonOffset_applied.factor = theFactor;
432 PolygonOffset_applied.units = theUnits;
433
434 TelUpdatePolygonOffsets (PolygonOffset_applied);
435}
436
2166f0fa
SK
437/*----------------------------------------------------------------------*/
438
17f65eb2 439const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
2166f0fa 440{
17f65eb2 441 if (theToApply && (AspectMarker_set != AspectMarker_applied))
2166f0fa 442 {
17f65eb2 443 if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
444 {
ca3c13d1 445 #if !defined(GL_ES_VERSION_2_0)
17f65eb2 446 glPointSize (AspectMarker_set->Scale());
447 #ifdef HAVE_GL2PS
448 gl2psPointSize (AspectMarker_set->Scale());
449 #endif
ca3c13d1 450 #endif
17f65eb2 451 }
2166f0fa
SK
452 AspectMarker_applied = AspectMarker_set;
453 }
454 return AspectMarker_set;
455}
456
457/*----------------------------------------------------------------------*/
458
a174a3c5 459const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
2166f0fa 460{
a174a3c5 461 if (theWithApply)
2166f0fa 462 {
a174a3c5 463 AspectText_applied = AspectText_set;
464 TextParam_applied = TextParam_set;
2166f0fa 465 }
a174a3c5 466
2166f0fa
SK
467 return AspectText_set;
468}