0024739: TKOpenGl - port ray-tracing from OpenCL to GLSL for better integration and...
[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 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
47static 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 69void 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
205const 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
214const 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
223const 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
232const 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 241const 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 254const 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 282const 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
294const 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 320const 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 454const 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 472const 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}