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