0027105: Make code ISO-compliant [-Wpedantic fixes]
[occt.git] / src / OpenGl / OpenGl_Workspace.cxx
1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <OpenGl_Workspace.hxx>
17
18 #include <InterfaceGraphic.hxx>
19
20 #include <OpenGl_ArbFBO.hxx>
21 #include <OpenGl_AspectLine.hxx>
22 #include <OpenGl_AspectFace.hxx>
23 #include <OpenGl_AspectMarker.hxx>
24 #include <OpenGl_AspectText.hxx>
25 #include <OpenGl_Context.hxx>
26 #include <OpenGl_Element.hxx>
27 #include <OpenGl_FrameBuffer.hxx>
28 #include <OpenGl_GlCore15.hxx>
29 #include <OpenGl_SceneGeometry.hxx>
30 #include <OpenGl_Structure.hxx>
31 #include <OpenGl_Sampler.hxx>
32 #include <OpenGl_Texture.hxx>
33 #include <OpenGl_View.hxx>
34 #include <OpenGl_Window.hxx>
35
36 #include <Graphic3d_TextureParams.hxx>
37 #include <Graphic3d_TransformUtils.hxx>
38
39 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,Standard_Transient)
40 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter,OpenGl_RenderFilter)
41
42 #ifdef HAVE_GL2PS
43   #include <gl2ps.h>
44   /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
45      Pragma comment for gl2ps.lib is defined only here. */
46   #ifdef _MSC_VER
47   #pragma comment( lib, "gl2ps.lib" )
48   #endif
49 #endif
50
51 namespace
52 {
53   static const TEL_COLOUR  THE_WHITE_COLOR = { { 1.0f, 1.0f, 1.0f, 1.0f } };
54   static const OpenGl_Vec4 THE_BLACK_COLOR      (0.0f, 0.0f, 0.0f, 1.0f);
55
56   static const OpenGl_AspectLine myDefaultAspectLine;
57   static const OpenGl_AspectFace myDefaultAspectFace;
58   static const OpenGl_AspectMarker myDefaultAspectMarker;
59
60   static const OpenGl_Matrix myDefaultMatrix =
61   {
62     {{ 1.0F, 0.0F, 0.0F, 0.0F },
63      { 0.0F, 1.0F, 0.0F, 0.0F },
64      { 0.0F, 0.0F, 1.0F, 0.0F },
65      { 0.0F, 0.0F, 0.0F, 1.0F }}
66   };
67
68 }
69
70 // =======================================================================
71 // function : Init
72 // purpose  :
73 // =======================================================================
74 void OpenGl_Material::Init (const OPENGL_SURF_PROP& theProp)
75 {
76   // ambient component
77   if (theProp.color_mask & OPENGL_AMBIENT_MASK)
78   {
79     const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb;
80     Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb,
81                            aSrcAmb[1] * theProp.amb,
82                            aSrcAmb[2] * theProp.amb,
83                            1.0f);
84   }
85   else
86   {
87     Ambient = THE_BLACK_COLOR;
88   }
89
90   // diffusion component
91   if (theProp.color_mask & OPENGL_DIFFUSE_MASK)
92   {
93     const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb;
94     Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff,
95                            aSrcDif[1] * theProp.diff,
96                            aSrcDif[2] * theProp.diff,
97                            1.0f);
98   }
99   else
100   {
101     Diffuse = THE_BLACK_COLOR;
102   }
103
104   // specular component
105   if (theProp.color_mask & OPENGL_SPECULAR_MASK)
106   {
107     const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb;
108     Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec,
109                             aSrcSpe[1] * theProp.spec,
110                             aSrcSpe[2] * theProp.spec,
111                             1.0f);
112   }
113   else
114   {
115     Specular = THE_BLACK_COLOR;
116   }
117
118   // emission component
119   if (theProp.color_mask & OPENGL_EMISSIVE_MASK)
120   {
121     const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb;
122     Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv,
123                             aSrcEms[1] * theProp.emsv,
124                             aSrcEms[2] * theProp.emsv,
125                             1.0f);
126   }
127   else
128   {
129     Emission = THE_BLACK_COLOR;
130   }
131
132   ChangeShine()        = theProp.shine;
133   ChangeTransparency() = theProp.trans;
134 }
135
136 // =======================================================================
137 // function : OpenGl_Workspace
138 // purpose  :
139 // =======================================================================
140 OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Window)& theWindow)
141 : NamedStatus (0),
142   HighlightColor (&THE_WHITE_COLOR),
143   myView (theView),
144   myWindow (theWindow),
145   myGlContext (!theWindow.IsNull() ? theWindow->GetGlContext() : NULL),
146   myUseZBuffer    (Standard_True),
147   myUseDepthWrite (Standard_True),
148   myUseGLLight (Standard_True),
149   //
150   AspectLine_set (&myDefaultAspectLine),
151   AspectLine_applied (NULL),
152   AspectFace_set (&myDefaultAspectFace),
153   AspectFace_applied (NULL),
154   AspectMarker_set (&myDefaultAspectMarker),
155   AspectMarker_applied (NULL),
156   ViewMatrix_applied (&myDefaultMatrix),
157   StructureMatrix_applied (&myDefaultMatrix),
158   myCullingMode (TelCullUndefined),
159   myModelViewMatrix (myDefaultMatrix),
160   PolygonOffset_applied (THE_DEFAULT_POFFSET)
161 {
162   if (!myGlContext.IsNull() && myGlContext->MakeCurrent())
163   {
164     myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
165
166     if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
167     {
168       // share and register for release once the resource is no longer used
169       myLineAttribs = new OpenGl_LineAttributes();
170       myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs);
171       myLineAttribs->Init (myGlContext);
172     }
173
174     // General initialization of the context
175
176   #if !defined(GL_ES_VERSION_2_0)
177     if (myGlContext->core11 != NULL)
178     {
179       // Eviter d'avoir les faces mal orientees en noir.
180       // Pourrait etre utiliser pour detecter les problemes d'orientation
181       glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
182
183       // Optimisation pour le Fog et l'antialiasing
184       glHint (GL_FOG_HINT,            GL_FASTEST);
185       glHint (GL_POINT_SMOOTH_HINT,   GL_FASTEST);
186     }
187
188     glHint (GL_LINE_SMOOTH_HINT,    GL_FASTEST);
189     glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
190   #endif
191   }
192
193   myDefaultCappingAlgoFilter         = new OpenGl_CappingAlgoFilter();
194   myNoneCulling.ChangeCullingMode()  = TelCullNone;
195   myNoneCulling.ChangeEdge()         = 0;
196   myFrontCulling.ChangeCullingMode() = TelCullBack;
197   myFrontCulling.ChangeEdge()        = 0;
198 }
199
200 // =======================================================================
201 // function : ~OpenGl_Workspace
202 // purpose  :
203 // =======================================================================
204 OpenGl_Workspace::~OpenGl_Workspace()
205 {
206   if (!myLineAttribs.IsNull())
207   {
208     myLineAttribs.Nullify();
209     myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
210   }
211 }
212
213 // =======================================================================
214 // function : Activate
215 // purpose  :
216 // =======================================================================
217 Standard_Boolean OpenGl_Workspace::Activate()
218 {
219   if (myWindow.IsNull() || !myWindow->Activate())
220   {
221     return Standard_False;
222   }
223
224   ViewMatrix_applied      = &myDefaultMatrix;
225   StructureMatrix_applied = &myDefaultMatrix;
226
227   ResetAppliedAspect();
228
229   return Standard_True;
230 }
231
232 //=======================================================================
233 //function : ResetAppliedAspect
234 //purpose  : Sets default values of GL parameters in accordance with default aspects
235 //=======================================================================
236 void OpenGl_Workspace::ResetAppliedAspect()
237 {
238   myGlContext->BindDefaultVao();
239
240   NamedStatus           = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
241   HighlightColor        = &THE_WHITE_COLOR;
242   AspectLine_set        = &myDefaultAspectLine;
243   AspectLine_applied    = NULL;
244   AspectFace_set        = &myDefaultAspectFace;
245   AspectFace_applied    = NULL;
246   AspectMarker_set      = &myDefaultAspectMarker;
247   AspectMarker_applied  = NULL;
248   PolygonOffset_applied = THE_DEFAULT_POFFSET;
249   myCullingMode         = TelCullUndefined;
250
251   AspectLine(Standard_True);
252   AspectFace(Standard_True);
253   AspectMarker(Standard_True);
254   AspectText(Standard_True);
255
256   myGlContext->SetTypeOfLine (myDefaultAspectLine.Type());
257   myGlContext->SetLineWidth  (myDefaultAspectLine.Width());
258 }
259
260 // =======================================================================
261 // function : DisableTexture
262 // purpose  :
263 // =======================================================================
264 Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
265 {
266   if (myTextureBound.IsNull())
267   {
268     return myTextureBound;
269   }
270
271   const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
272   if (!aSampler.IsNull())
273   {
274     aSampler->Unbind (*myGlContext);
275   }
276
277 #if !defined(GL_ES_VERSION_2_0)
278   // reset texture matrix because some code may expect it is identity
279   if (myGlContext->core11 != NULL)
280   {
281     GLint aMatrixMode = GL_TEXTURE;
282     glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
283     glMatrixMode (GL_TEXTURE);
284     glLoadIdentity();
285     glMatrixMode (aMatrixMode);
286   }
287 #endif
288
289   myTextureBound->Unbind (myGlContext);
290   switch (myTextureBound->GetTarget())
291   {
292   #if !defined(GL_ES_VERSION_2_0)
293     case GL_TEXTURE_1D:
294     {
295       if (myGlContext->core11 != NULL)
296       {
297         if (myTextureBound->GetParams()->GenMode() != GL_NONE)
298         {
299           glDisable (GL_TEXTURE_GEN_S);
300         }
301         glDisable (GL_TEXTURE_1D);
302       }
303       break;
304     }
305   #endif
306     case GL_TEXTURE_2D:
307     {
308     #if !defined(GL_ES_VERSION_2_0)
309       if (myGlContext->core11 != NULL)
310       {
311         if (myTextureBound->GetParams()->GenMode() != GL_NONE)
312         {
313           glDisable (GL_TEXTURE_GEN_S);
314           glDisable (GL_TEXTURE_GEN_T);
315           if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
316           {
317             glDisable (GL_POINT_SPRITE);
318           }
319         }
320         glDisable (GL_TEXTURE_2D);
321       }
322     #endif
323       break;
324     }
325     default: break;
326   }
327
328   Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
329   myTextureBound.Nullify();
330   return aPrevTexture;
331 }
332
333 // =======================================================================
334 // function : setTextureParams
335 // purpose  :
336 // =======================================================================
337 void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)&                theTexture,
338                                          const Handle(Graphic3d_TextureParams)& theParams)
339 {
340   const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
341   if (aParams.IsNull())
342   {
343     return;
344   }
345
346 #if !defined(GL_ES_VERSION_2_0)
347   if (myGlContext->core11 != NULL)
348   {
349     GLint anEnvMode = GL_MODULATE; // lighting mode
350     if (!aParams->IsModulate())
351     {
352       anEnvMode = GL_DECAL;
353       if (theTexture->GetFormat() == GL_ALPHA
354        || theTexture->GetFormat() == GL_LUMINANCE)
355       {
356         anEnvMode = GL_REPLACE;
357       }
358     }
359
360     // setup generation of texture coordinates
361     switch (aParams->GenMode())
362     {
363       case Graphic3d_TOTM_OBJECT:
364       {
365         glTexGeni  (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
366         glTexGenfv (GL_S, GL_OBJECT_PLANE,     aParams->GenPlaneS().GetData());
367         if (theTexture->GetTarget() != GL_TEXTURE_1D)
368         {
369           glTexGeni  (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
370           glTexGenfv (GL_T, GL_OBJECT_PLANE,     aParams->GenPlaneT().GetData());
371         }
372         break;
373       }
374       case Graphic3d_TOTM_SPHERE:
375       {
376         glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
377         if (theTexture->GetTarget() != GL_TEXTURE_1D)
378         {
379           glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
380         }
381         break;
382       }
383       case Graphic3d_TOTM_EYE:
384       {
385         myGlContext->WorldViewState.Push();
386
387         myGlContext->WorldViewState.SetIdentity();
388         myGlContext->ApplyWorldViewMatrix();
389
390         glTexGeni  (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
391         glTexGenfv (GL_S, GL_EYE_PLANE,        aParams->GenPlaneS().GetData());
392
393         if (theTexture->GetTarget() != GL_TEXTURE_1D)
394         {
395           glTexGeni  (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
396           glTexGenfv (GL_T, GL_EYE_PLANE,        aParams->GenPlaneT().GetData());
397         }
398
399         myGlContext->WorldViewState.Pop();
400
401         break;
402       }
403       case Graphic3d_TOTM_SPRITE:
404       {
405         if (myGlContext->core20fwd != NULL)
406         {
407           glEnable  (GL_POINT_SPRITE);
408           glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
409           anEnvMode = GL_REPLACE;
410           myGlContext->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
411         }
412         break;
413       }
414       case Graphic3d_TOTM_MANUAL:
415       default: break;
416     }
417
418     // setup lighting
419     glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
420   }
421 #endif
422
423   // get active sampler object to override default texture parameters
424   const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
425
426   // setup texture filtering and wrapping
427   //if (theTexture->GetParams() != theParams)
428   const GLenum aFilter   = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
429   const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
430   switch (theTexture->GetTarget())
431   {
432   #if !defined(GL_ES_VERSION_2_0)
433     case GL_TEXTURE_1D:
434     {
435       if (aSampler.IsNull() || !aSampler->IsValid())
436       {
437         glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
438         glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
439         glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,     aWrapMode);
440       }
441       else
442       {
443         aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
444         aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
445         aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S,     aWrapMode);
446       }
447
448       break;
449     }
450   #endif
451     case GL_TEXTURE_2D:
452     {
453       GLenum aFilterMin = aFilter;
454       if (theTexture->HasMipmaps())
455       {
456         aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
457         if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
458         {
459           aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
460         }
461         else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
462         {
463           aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
464         }
465
466         if (myGlContext->extAnis)
467         {
468           // setup degree of anisotropy filter
469           const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
470           GLint aDegree;
471           switch (aParams->AnisoFilter())
472           {
473             case Graphic3d_LOTA_QUALITY:
474             {
475               aDegree = aMaxDegree;
476               break;
477             }
478             case Graphic3d_LOTA_MIDDLE:
479             {
480               aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
481               break;
482             }
483             case Graphic3d_LOTA_FAST:
484             {
485               aDegree = 2;
486               break;
487             }
488             case Graphic3d_LOTA_OFF:
489             default:
490             {
491               aDegree = 1;
492               break;
493             }
494           }
495
496           if (aSampler.IsNull() || !aSampler->IsValid())
497           {
498             glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
499           }
500           else
501           {
502             aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
503           }
504         }
505       }
506
507       if (aSampler.IsNull() || !aSampler->IsValid())
508       {
509         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
510         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
511         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     aWrapMode);
512         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     aWrapMode);
513       }
514       else
515       {
516         aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
517         aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
518         aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S,     aWrapMode);
519         aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T,     aWrapMode);
520       }
521
522       break;
523     }
524     default: break;
525   }
526
527   switch (theTexture->GetTarget())
528   {
529   #if !defined(GL_ES_VERSION_2_0)
530     case GL_TEXTURE_1D:
531     {
532       if (myGlContext->core11 != NULL)
533       {
534         if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
535         {
536           glEnable (GL_TEXTURE_GEN_S);
537         }
538         glEnable (GL_TEXTURE_1D);
539       }
540       break;
541     }
542   #endif
543     case GL_TEXTURE_2D:
544     {
545     #if !defined(GL_ES_VERSION_2_0)
546       if (myGlContext->core11 != NULL)
547       {
548         if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
549         {
550           glEnable (GL_TEXTURE_GEN_S);
551           glEnable (GL_TEXTURE_GEN_T);
552         }
553         glEnable (GL_TEXTURE_2D);
554       }
555     #endif
556       break;
557     }
558     default: break;
559   }
560
561   theTexture->SetParams (aParams);
562 }
563
564 // =======================================================================
565 // function : EnableTexture
566 // purpose  :
567 // =======================================================================
568 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)&          theTexture,
569                                                         const Handle(Graphic3d_TextureParams)& theParams)
570 {
571   if (theTexture.IsNull() || !theTexture->IsValid())
572   {
573     return DisableTexture();
574   }
575
576   if (myTextureBound == theTexture
577    && (theParams.IsNull() || theParams == theTexture->GetParams()))
578   {
579     // already bound
580     return myTextureBound;
581   }
582
583   Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
584   myTextureBound = theTexture;
585   myTextureBound->Bind (myGlContext);
586   setTextureParams (myTextureBound, theParams);
587
588   // If custom sampler object is available it will be
589   // used for overriding default texture parameters
590   const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
591
592   if (!aSampler.IsNull() && aSampler->IsValid())
593   {
594     aSampler->Bind (*myGlContext);
595   }
596
597   return aPrevTexture;
598 }
599
600 // =======================================================================
601 // function : TelUpdatePolygonOffsets
602 // purpose  :
603 // =======================================================================
604 static void TelUpdatePolygonOffsets (const TEL_POFFSET_PARAM& theOffsetData)
605 {
606   if ((theOffsetData.mode & Aspect_POM_Fill) == Aspect_POM_Fill)
607   {
608     glEnable (GL_POLYGON_OFFSET_FILL);
609   }
610   else
611   {
612     glDisable (GL_POLYGON_OFFSET_FILL);
613   }
614
615 #if !defined(GL_ES_VERSION_2_0)
616   if ((theOffsetData.mode & Aspect_POM_Line) == Aspect_POM_Line)
617   {
618     glEnable (GL_POLYGON_OFFSET_LINE);
619   }
620   else
621   {
622     glDisable (GL_POLYGON_OFFSET_LINE);
623   }
624
625   if ((theOffsetData.mode & Aspect_POM_Point) == Aspect_POM_Point)
626   {
627     glEnable (GL_POLYGON_OFFSET_POINT);
628   }
629   else
630   {
631     glDisable (GL_POLYGON_OFFSET_POINT);
632   }
633 #endif
634
635   glPolygonOffset (theOffsetData.factor, theOffsetData.units);
636 }
637
638 // =======================================================================
639 // function : updateMaterial
640 // purpose  :
641 // =======================================================================
642 void OpenGl_Workspace::updateMaterial (const int theFlag)
643 {
644   // Case of hidden line
645   if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE)
646   {
647     myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
648     myAspectFaceHl.ChangeIntFront().matcol     = myView->BackgroundColor();
649     myAspectFaceHl.ChangeIntFront().color_mask = 0;
650     myAspectFaceHl.ChangeIntFront().color_mask = 0;
651
652     AspectFace_set = &myAspectFaceHl;
653     return;
654   }
655
656   const OPENGL_SURF_PROP* aProps = &AspectFace_set->IntFront();
657   GLenum aFace = GL_FRONT_AND_BACK;
658   if (theFlag == TEL_BACK_MATERIAL)
659   {
660     aFace  = GL_BACK;
661     aProps = &AspectFace_set->IntBack();
662   }
663   else if (AspectFace_set->DistinguishingMode() == TOn
664         && !(NamedStatus & OPENGL_NS_RESMAT))
665   {
666     aFace = GL_FRONT;
667   }
668
669   myMatTmp.Init (*aProps);
670
671   // handling transparency
672   if (NamedStatus & OPENGL_NS_2NDPASSDO)
673   {
674     // second pass
675     myMatTmp.Diffuse.a() = aProps->env_reflexion;
676   }
677   else
678   {
679     if (aProps->env_reflexion != 0.0f)
680     {
681       // if the material reflects the environment scene, the second pass is needed
682       NamedStatus |= OPENGL_NS_2NDPASSNEED;
683     }
684
685     if (aProps->trans != 1.0f)
686     {
687       // render transparent
688       myMatTmp.Diffuse.a() = aProps->trans;
689       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
690       glEnable    (GL_BLEND);
691       if (myUseDepthWrite)
692       {
693         glDepthMask (GL_FALSE);
694       }
695     }
696     else
697     {
698       // render opaque
699       if ((NamedStatus & OPENGL_NS_ANTIALIASING) == 0)
700       {
701         glBlendFunc (GL_ONE, GL_ZERO);
702         glDisable   (GL_BLEND);
703       }
704       if (myUseDepthWrite)
705       {
706         glDepthMask (GL_TRUE);
707       }
708     }
709   }
710
711   // do not update material properties in case of zero reflection mode,
712   // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
713   if (aProps->color_mask == 0)
714   {
715     return;
716   }
717
718   // reset material
719   if (NamedStatus & OPENGL_NS_RESMAT)
720   {
721   #if !defined(GL_ES_VERSION_2_0)
722     if (myGlContext->core11 != NULL)
723     {
724       myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT,   myMatTmp.Ambient.GetData());
725       myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE,   myMatTmp.Diffuse.GetData());
726       myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR,  myMatTmp.Specular.GetData());
727       myGlContext->core11->glMaterialfv (aFace, GL_EMISSION,  myMatTmp.Emission.GetData());
728       myGlContext->core11->glMaterialf  (aFace, GL_SHININESS, myMatTmp.Shine());
729     }
730   #endif
731
732     if (theFlag == TEL_FRONT_MATERIAL)
733     {
734       myMatFront = myMatTmp;
735       myMatBack  = myMatTmp;
736     }
737     else
738     {
739       myMatBack = myMatTmp;
740     }
741
742     NamedStatus &= ~OPENGL_NS_RESMAT;
743     return;
744   }
745
746   // reduce updates
747   OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
748                          ? myMatFront
749                          : myMatBack;
750 #if !defined(GL_ES_VERSION_2_0)
751   if (myGlContext->core11 != NULL)
752   {
753     if (myMatTmp.Ambient.r() != anOld.Ambient.r()
754      || myMatTmp.Ambient.g() != anOld.Ambient.g()
755      || myMatTmp.Ambient.b() != anOld.Ambient.b())
756     {
757       myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
758     }
759     if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
760      || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
761      || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
762      || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
763     {
764       myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
765     }
766     if (myMatTmp.Specular.r() != anOld.Specular.r()
767      || myMatTmp.Specular.g() != anOld.Specular.g()
768      || myMatTmp.Specular.b() != anOld.Specular.b())
769     {
770       myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
771     }
772     if (myMatTmp.Emission.r() != anOld.Emission.r()
773      || myMatTmp.Emission.g() != anOld.Emission.g()
774      || myMatTmp.Emission.b() != anOld.Emission.b())
775     {
776       myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
777     }
778     if (myMatTmp.Shine() != anOld.Shine())
779     {
780       myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
781     }
782   }
783 #endif
784   anOld = myMatTmp;
785   if (aFace == GL_FRONT_AND_BACK)
786   {
787     myMatBack = myMatTmp;
788   }
789 }
790
791 // =======================================================================
792 // function : SetAspectLine
793 // purpose  :
794 // =======================================================================
795 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
796 {
797   const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
798   AspectLine_set = AnAspect;
799   return AspectLine_old;
800 }
801
802 // =======================================================================
803 // function : SetAspectFace
804 // purpose  :
805 // =======================================================================
806 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
807 {
808   const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
809   AspectFace_set = AnAspect;
810   return AspectFace_old;
811 }
812
813 // =======================================================================
814 // function : SetAspectMarker
815 // purpose  :
816 // =======================================================================
817 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
818 {
819   const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
820   AspectMarker_set = AnAspect;
821   return AspectMarker_old;
822 }
823
824 // =======================================================================
825 // function : SetAspectText
826 // purpose  :
827 // =======================================================================
828 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
829 {
830   const OpenGl_AspectText *AspectText_old = AspectText_set;
831   AspectText_set = AnAspect;
832   return AspectText_old;
833 }
834
835 // =======================================================================
836 // function : AspectLine
837 // purpose  :
838 // =======================================================================
839 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean theWithApply)
840 {
841   if (theWithApply)
842   {
843     AspectLine_applied = AspectLine_set;
844   }
845
846   return AspectLine_set;
847 }
848
849 // =======================================================================
850 // function : AspectFace
851 // purpose  :
852 // =======================================================================
853 const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
854 {
855   if (!theToApply)
856   {
857     return AspectFace_set;
858   }
859
860   if (myView->BackfacingModel() == Graphic3d_TOBM_AUTOMATIC)
861   {
862     // manage back face culling mode, disable culling when clipping is enabled
863     TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn()
864                              || AspectFace_set->InteriorStyle() == Aspect_IS_HATCH)
865                              ? TelCullNone
866                              : (TelCullMode )AspectFace_set->CullingMode();
867     if (aCullingMode != TelCullNone
868      && !(NamedStatus & OPENGL_NS_2NDPASSDO))
869     {
870       // disable culling in case of translucent shading aspect
871       if (AspectFace_set->IntFront().trans != 1.0f)
872       {
873         aCullingMode = TelCullNone;
874       }
875     }
876     if (myCullingMode != aCullingMode)
877     {
878       myCullingMode = aCullingMode;
879       switch (myCullingMode)
880       {
881         case TelCullNone:
882         case TelCullUndefined:
883         {
884           glDisable (GL_CULL_FACE);
885           break;
886         }
887         case TelCullFront:
888         {
889           glCullFace (GL_FRONT);
890           glEnable (GL_CULL_FACE);
891           break;
892         }
893         case TelCullBack:
894         {
895           glCullFace (GL_BACK);
896           glEnable (GL_CULL_FACE);
897           break;
898         }
899       }
900     }
901   }
902
903   if (AspectFace_set == AspectFace_applied)
904   {
905     return AspectFace_set;
906   }
907
908 #if !defined(GL_ES_VERSION_2_0)
909   const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle();
910   if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle)
911   {
912     switch (anIntstyle)
913     {
914       case Aspect_IS_EMPTY:
915       case Aspect_IS_HOLLOW:
916       {
917         glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
918         break;
919       }
920       case Aspect_IS_HATCH:
921       {
922         glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
923         myLineAttribs->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID);
924         break;
925       }
926       case Aspect_IS_SOLID:
927       case Aspect_IS_HIDDENLINE:
928       {
929         glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
930         if (myGlContext->core11 != NULL)
931         {
932           glDisable (GL_POLYGON_STIPPLE);
933         }
934         break;
935       }
936       case Aspect_IS_POINT:
937       {
938         glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
939         break;
940       }
941     }
942   }
943
944   if (anIntstyle == Aspect_IS_HATCH)
945   {
946     const Tint hatchstyle = AspectFace_set->Hatch();
947     if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle)
948     {
949       myLineAttribs->SetTypeOfHatch (hatchstyle);
950     }
951   }
952 #endif
953
954   // Aspect_POM_None means: do not change current settings
955   if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
956   {
957     if (PolygonOffset_applied.mode   != AspectFace_set->PolygonOffset().mode
958      || PolygonOffset_applied.factor != AspectFace_set->PolygonOffset().factor
959      || PolygonOffset_applied.units  != AspectFace_set->PolygonOffset().units)
960     {
961       SetPolygonOffset (AspectFace_set->PolygonOffset().mode,
962                         AspectFace_set->PolygonOffset().factor,
963                         AspectFace_set->PolygonOffset().units);
964     }
965   }
966
967   updateMaterial (TEL_FRONT_MATERIAL);
968   if (AspectFace_set->DistinguishingMode() == TOn)
969   {
970     updateMaterial (TEL_BACK_MATERIAL);
971   }
972
973   if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
974   {
975     if (AspectFace_set->DoTextureMap())
976     {
977       EnableTexture (AspectFace_set->TextureRes (myGlContext),
978                      AspectFace_set->TextureParams());
979     }
980     else
981     {
982       DisableTexture();
983     }
984   }
985
986   AspectFace_applied = AspectFace_set;
987   return AspectFace_set;
988 }
989
990 //=======================================================================
991 //function : SetPolygonOffset
992 //purpose  :
993 //=======================================================================
994 void OpenGl_Workspace::SetPolygonOffset (int theMode,
995                                          Standard_ShortReal theFactor,
996                                          Standard_ShortReal theUnits)
997 {
998   PolygonOffset_applied.mode   = theMode;
999   PolygonOffset_applied.factor = theFactor;
1000   PolygonOffset_applied.units  = theUnits;
1001
1002   TelUpdatePolygonOffsets (PolygonOffset_applied);
1003 }
1004
1005 // =======================================================================
1006 // function : AspectMarker
1007 // purpose  :
1008 // =======================================================================
1009 const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
1010 {
1011   if (theToApply && (AspectMarker_set != AspectMarker_applied))
1012   {
1013     if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
1014     {
1015     #if !defined(GL_ES_VERSION_2_0)
1016       glPointSize (AspectMarker_set->Scale());
1017     #ifdef HAVE_GL2PS
1018       gl2psPointSize (AspectMarker_set->Scale());
1019     #endif
1020     #endif
1021     }
1022     AspectMarker_applied = AspectMarker_set;
1023   }
1024   return AspectMarker_set;
1025 }
1026
1027 // =======================================================================
1028 // function : AspectText
1029 // purpose  :
1030 // =======================================================================
1031 const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
1032 {
1033   if (theWithApply)
1034   {
1035     AspectText_applied = AspectText_set;
1036   }
1037
1038   return AspectText_set;
1039 }
1040
1041 // =======================================================================
1042 // function : Width
1043 // purpose  :
1044 // =======================================================================
1045 Standard_Integer OpenGl_Workspace::Width()  const
1046 {
1047   return !myView->GlWindow().IsNull() ? myView->GlWindow()->Width() : 0;
1048 }
1049
1050 // =======================================================================
1051 // function : Height
1052 // purpose  :
1053 // =======================================================================
1054 Standard_Integer OpenGl_Workspace::Height() const
1055 {
1056   return !myView->GlWindow().IsNull() ? myView->GlWindow()->Height() : 0;
1057 }
1058
1059 // =======================================================================
1060 // function : UseGLLight
1061 // purpose  :
1062 // =======================================================================
1063 Standard_Boolean OpenGl_Workspace::UseGLLight() const
1064 {
1065   return myView->IsGLLightEnabled();
1066 }
1067
1068 // =======================================================================
1069 // function : AntiAliasingMode
1070 // purpose  :
1071 // =======================================================================
1072 Standard_Integer OpenGl_Workspace::AntiAliasingMode() const
1073 {
1074   return myView->IsAntialiasingEnabled();
1075 }
1076
1077 // =======================================================================
1078 // function : IsCullingEnabled
1079 // purpose  :
1080 // =======================================================================
1081 Standard_Boolean OpenGl_Workspace::IsCullingEnabled() const
1082 {
1083   return myView->IsCullingEnabled();
1084 }
1085
1086 // =======================================================================
1087 // function : FBOCreate
1088 // purpose  :
1089 // =======================================================================
1090 Handle(OpenGl_FrameBuffer) OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth,
1091                                                         const Standard_Integer theHeight)
1092 {
1093   // activate OpenGL context
1094   if (!Activate())
1095     return Handle(OpenGl_FrameBuffer)();
1096
1097   // create the FBO
1098   const Handle(OpenGl_Context)& aCtx = GetGlContext();
1099   Handle(OpenGl_FrameBuffer) aFrameBuffer = new OpenGl_FrameBuffer();
1100   if (!aFrameBuffer->Init (aCtx, theWidth, theHeight, GL_RGBA8, GL_DEPTH24_STENCIL8, 0))
1101   {
1102     aFrameBuffer->Release (aCtx.operator->());
1103     return Handle(OpenGl_FrameBuffer)();
1104   }
1105   return aFrameBuffer;
1106 }
1107
1108 // =======================================================================
1109 // function : FBORelease
1110 // purpose  :
1111 // =======================================================================
1112 void OpenGl_Workspace::FBORelease (Handle(OpenGl_FrameBuffer)& theFbo)
1113 {
1114   // activate OpenGL context
1115   if (!Activate()
1116    || theFbo.IsNull())
1117   {
1118     return;
1119   }
1120
1121   theFbo->Release (GetGlContext().operator->());
1122   theFbo.Nullify();
1123 }
1124
1125 inline bool getDataFormat (const Image_PixMap& theData,
1126                            GLenum&             thePixelFormat,
1127                            GLenum&             theDataType)
1128 {
1129   thePixelFormat = GL_RGB;
1130   theDataType    = GL_UNSIGNED_BYTE;
1131   switch (theData.Format())
1132   {
1133   #if !defined(GL_ES_VERSION_2_0)
1134     case Image_PixMap::ImgGray:
1135       thePixelFormat = GL_DEPTH_COMPONENT;
1136       theDataType    = GL_UNSIGNED_BYTE;
1137       return true;
1138     case Image_PixMap::ImgGrayF:
1139       thePixelFormat = GL_DEPTH_COMPONENT;
1140       theDataType    = GL_FLOAT;
1141       return true;
1142     case Image_PixMap::ImgBGR:
1143       thePixelFormat = GL_BGR;
1144       theDataType    = GL_UNSIGNED_BYTE;
1145       return true;
1146     case Image_PixMap::ImgBGRA:
1147     case Image_PixMap::ImgBGR32:
1148       thePixelFormat = GL_BGRA;
1149       theDataType    = GL_UNSIGNED_BYTE;
1150       return true;
1151     case Image_PixMap::ImgBGRF:
1152       thePixelFormat = GL_BGR;
1153       theDataType    = GL_FLOAT;
1154       return true;
1155     case Image_PixMap::ImgBGRAF:
1156       thePixelFormat = GL_BGRA;
1157       theDataType    = GL_FLOAT;
1158       return true;
1159   #else
1160     case Image_PixMap::ImgGray:
1161     case Image_PixMap::ImgGrayF:
1162     case Image_PixMap::ImgBGR:
1163     case Image_PixMap::ImgBGRA:
1164     case Image_PixMap::ImgBGR32:
1165     case Image_PixMap::ImgBGRF:
1166     case Image_PixMap::ImgBGRAF:
1167       return false;
1168   #endif
1169     case Image_PixMap::ImgRGB:
1170       thePixelFormat = GL_RGB;
1171       theDataType    = GL_UNSIGNED_BYTE;
1172       return true;
1173     case Image_PixMap::ImgRGBA:
1174     case Image_PixMap::ImgRGB32:
1175       thePixelFormat = GL_RGBA;
1176       theDataType    = GL_UNSIGNED_BYTE;
1177       return true;
1178     case Image_PixMap::ImgRGBF:
1179       thePixelFormat = GL_RGB;
1180       theDataType    = GL_FLOAT;
1181       return true;
1182     case Image_PixMap::ImgRGBAF:
1183       thePixelFormat = GL_RGBA;
1184       theDataType    = GL_FLOAT;
1185       return true;
1186     case Image_PixMap::ImgAlpha:
1187     case Image_PixMap::ImgAlphaF:
1188       return false; // GL_ALPHA is no more supported in core context
1189     case Image_PixMap::ImgUNKNOWN:
1190       return false;
1191   }
1192   return false;
1193 }
1194
1195 // =======================================================================
1196 // function : getAligned
1197 // purpose  :
1198 // =======================================================================
1199 inline Standard_Size getAligned (const Standard_Size theNumber,
1200                                  const Standard_Size theAlignment)
1201 {
1202   return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
1203 }
1204
1205 // =======================================================================
1206 // function : BufferDump
1207 // purpose  :
1208 // =======================================================================
1209 Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)& theFbo,
1210                                                Image_PixMap&                     theImage,
1211                                                const Graphic3d_BufferType&       theBufferType)
1212 {
1213   GLenum aFormat, aType;
1214   if (theImage.IsEmpty()
1215    || !getDataFormat (theImage, aFormat, aType)
1216    || !Activate())
1217   {
1218     return Standard_False;
1219   }
1220 #if !defined(GL_ES_VERSION_2_0)
1221   GLint aReadBufferPrev = GL_BACK;
1222   if (theBufferType == Graphic3d_BT_Depth
1223    && aFormat != GL_DEPTH_COMPONENT)
1224   {
1225     return Standard_False;
1226   }
1227 #else
1228   (void )theBufferType;
1229 #endif
1230
1231   // bind FBO if used
1232   if (!theFbo.IsNull() && theFbo->IsValid())
1233   {
1234     theFbo->BindBuffer (GetGlContext());
1235   }
1236   else
1237   {
1238   #if !defined(GL_ES_VERSION_2_0)
1239     glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
1240     GLint aDrawBufferPrev = GL_BACK;
1241     glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
1242     glReadBuffer (aDrawBufferPrev);
1243   #endif
1244   }
1245
1246   // setup alignment
1247   const GLint anAligment   = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
1248   glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
1249   bool isBatchCopy = !theImage.IsTopDown();
1250
1251   const GLint   anExtraBytes       = GLint(theImage.RowExtraBytes());
1252   GLint         aPixelsWidth       = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
1253   Standard_Size aSizeRowBytesEstim = getAligned (theImage.SizePixelBytes() * aPixelsWidth, anAligment);
1254   if (anExtraBytes < anAligment)
1255   {
1256     aPixelsWidth = 0;
1257   }
1258   else if (aSizeRowBytesEstim != theImage.SizeRowBytes())
1259   {
1260     aPixelsWidth = 0;
1261     isBatchCopy  = false;
1262   }
1263 #if !defined(GL_ES_VERSION_2_0)
1264   glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth);
1265 #else
1266   if (aPixelsWidth != 0)
1267   {
1268     isBatchCopy = false;
1269   }
1270 #endif
1271
1272   if (!isBatchCopy)
1273   {
1274     // copy row by row
1275     for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
1276     {
1277       // Image_PixMap rows indexation always starts from the upper corner
1278       // while order in memory depends on the flag and processed by ChangeRow() method
1279       glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
1280     }
1281   }
1282   else
1283   {
1284     glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
1285   }
1286
1287   glPixelStorei (GL_PACK_ALIGNMENT,  1);
1288 #if !defined(GL_ES_VERSION_2_0)
1289   glPixelStorei (GL_PACK_ROW_LENGTH, 0);
1290 #endif
1291
1292   if (!theFbo.IsNull() && theFbo->IsValid())
1293   {
1294     theFbo->UnbindBuffer (GetGlContext());
1295   }
1296   else
1297   {
1298   #if !defined(GL_ES_VERSION_2_0)
1299     glReadBuffer (aReadBufferPrev);
1300   #endif
1301   }
1302   return Standard_True;
1303 }
1304
1305 // =======================================================================
1306 // function : CanRender
1307 // purpose  :
1308 // =======================================================================
1309 Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
1310 {
1311   Standard_Boolean aPrevFilterResult = Standard_True;
1312   if (!myPrevRenderFilter.IsNull())
1313   {
1314     aPrevFilterResult = myPrevRenderFilter->CanRender (theElement);
1315   }
1316   return aPrevFilterResult &&
1317     !OpenGl_Raytrace::IsRaytracedElement (theElement);
1318 }