0025219: Visualization, TKOpenGl - disable code paths unavailable on OpenGL ES 2.0
[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_GlCore15.hxx>
17
18 #include <InterfaceGraphic.hxx>
19
20 #include <OpenGl_AspectLine.hxx>
21 #include <OpenGl_AspectFace.hxx>
22 #include <OpenGl_AspectMarker.hxx>
23 #include <OpenGl_AspectText.hxx>
24 #include <OpenGl_Context.hxx>
25 #include <OpenGl_Element.hxx>
26 #include <OpenGl_FrameBuffer.hxx>
27 #include <OpenGl_Structure.hxx>
28 #include <OpenGl_Texture.hxx>
29 #include <OpenGl_View.hxx>
30 #include <OpenGl_Workspace.hxx>
31
32 #include <Graphic3d_TextureParams.hxx>
33
34 #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
35   #include <OpenGl_AVIWriter.hxx>
36 #endif
37
38 IMPLEMENT_STANDARD_HANDLE(OpenGl_Workspace,OpenGl_Window)
39 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,OpenGl_Window)
40
41 namespace
42 {
43   static const TEL_COLOUR  THE_WHITE_COLOR = { { 1.0f, 1.0f, 1.0f, 1.0f } };
44   static const OpenGl_Vec4 THE_BLACK_COLOR      (0.0f, 0.0f, 0.0f, 1.0f);
45
46   static const OpenGl_AspectLine myDefaultAspectLine;
47   static const OpenGl_AspectFace myDefaultAspectFace;
48   static const OpenGl_AspectMarker myDefaultAspectMarker;
49   static const OpenGl_AspectText myDefaultAspectText;
50
51   static const OpenGl_TextParam myDefaultTextParam =
52   {
53     16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
54   };
55
56   static const OpenGl_Matrix myDefaultMatrix =
57   {
58     {{ 1.0F, 0.0F, 0.0F, 0.0F },
59      { 0.0F, 1.0F, 0.0F, 0.0F },
60      { 0.0F, 0.0F, 1.0F, 0.0F },
61      { 0.0F, 0.0F, 0.0F, 1.0F }}
62   };
63
64 };
65
66 // =======================================================================
67 // function : Init
68 // purpose  :
69 // =======================================================================
70 void OpenGl_Material::Init (const OPENGL_SURF_PROP& theProp)
71 {
72   // ambient component
73   if (theProp.color_mask & OPENGL_AMBIENT_MASK)
74   {
75     const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb;
76     Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb,
77                            aSrcAmb[1] * theProp.amb,
78                            aSrcAmb[2] * theProp.amb,
79                            1.0f);
80   }
81   else
82   {
83     Ambient = THE_BLACK_COLOR;
84   }
85
86   // diffusion component
87   if (theProp.color_mask & OPENGL_DIFFUSE_MASK)
88   {
89     const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb;
90     Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff,
91                            aSrcDif[1] * theProp.diff,
92                            aSrcDif[2] * theProp.diff,
93                            1.0f);
94   }
95   else
96   {
97     Diffuse = THE_BLACK_COLOR;
98   }
99
100   // specular component
101   if (theProp.color_mask & OPENGL_SPECULAR_MASK)
102   {
103     const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb;
104     Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec,
105                             aSrcSpe[1] * theProp.spec,
106                             aSrcSpe[2] * theProp.spec,
107                             1.0f);
108   }
109   else
110   {
111     Specular = THE_BLACK_COLOR;
112   }
113
114   // emission component
115   if (theProp.color_mask & OPENGL_EMISSIVE_MASK)
116   {
117     const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb;
118     Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv,
119                             aSrcEms[1] * theProp.emsv,
120                             aSrcEms[2] * theProp.emsv,
121                             1.0f);
122   }
123   else
124   {
125     Emission = THE_BLACK_COLOR;
126   }
127
128   ChangeShine()        = theProp.shine;
129   ChangeTransparency() = theProp.trans;
130 }
131
132 // =======================================================================
133 // function : OpenGl_Workspace
134 // purpose  :
135 // =======================================================================
136 OpenGl_Workspace::OpenGl_Workspace (const Handle(Aspect_DisplayConnection)& theDisplayConnection,
137                                     const CALL_DEF_WINDOW&        theCWindow,
138                                     Aspect_RenderingContext       theGContext,
139                                     const Handle(OpenGl_Caps)&    theCaps,
140                                     const Handle(OpenGl_Context)& theShareCtx)
141 : OpenGl_Window (theDisplayConnection, theCWindow, theGContext, theCaps, theShareCtx),
142   NamedStatus (0),
143   HighlightColor (&THE_WHITE_COLOR),
144   //
145   myComputeInitStatus (OpenGl_RT_NONE),
146   myIsRaytraceDataValid (Standard_False),
147   myViewModificationStatus (0),
148   myLayersModificationStatus (0),
149   //
150   myRaytraceFilter       (new OpenGl_RaytraceFilter()),
151   myToRedrawGL           (Standard_True),
152   myAntiAliasingMode     (3),
153   myTransientDrawToFront (Standard_True),
154   myBackBufferRestored   (Standard_False),
155   myIsImmediateDrawn     (Standard_False),
156   myUseTransparency (Standard_False),
157   myUseZBuffer (Standard_False),
158   myUseDepthTest (Standard_True),
159   myUseGLLight (Standard_True),
160   myIsCullingEnabled (Standard_False),
161   myFrameCounter (0),
162   //
163   AspectLine_set (&myDefaultAspectLine),
164   AspectLine_applied (NULL),
165   AspectFace_set (&myDefaultAspectFace),
166   AspectFace_applied (NULL),
167   AspectMarker_set (&myDefaultAspectMarker),
168   AspectMarker_applied (NULL),
169   AspectText_set (&myDefaultAspectText),
170   AspectText_applied (NULL),
171   TextParam_set (&myDefaultTextParam),
172   TextParam_applied (NULL),
173   ViewMatrix_applied (&myDefaultMatrix),
174   StructureMatrix_applied (&myDefaultMatrix),
175   myCullingMode (TelCullUndefined),
176   myModelViewMatrix (myDefaultMatrix),
177   PolygonOffset_applied (THE_DEFAULT_POFFSET)
178 {
179   myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
180
181   if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
182   {
183     // share and register for release once the resource is no longer used
184     myLineAttribs = new OpenGl_LineAttributes();
185     myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs);
186     myLineAttribs->Init (myGlContext);
187   }
188
189   // General initialization of the context
190
191 #if !defined(GL_ES_VERSION_2_0)
192   // Eviter d'avoir les faces mal orientees en noir.
193   // Pourrait etre utiliser pour detecter les problemes d'orientation
194   glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
195
196   // Optimisation pour le Fog et l'antialiasing
197   glHint (GL_FOG_HINT,            GL_FASTEST);
198   glHint (GL_POINT_SMOOTH_HINT,   GL_FASTEST);
199   glHint (GL_LINE_SMOOTH_HINT,    GL_FASTEST);
200   glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
201 #endif
202
203   // AA mode
204   const char* anAaEnv = ::getenv ("CALL_OPENGL_ANTIALIASING_MODE");
205   if (anAaEnv != NULL)
206   {
207     int v;
208     if (sscanf (anAaEnv, "%d", &v) > 0) myAntiAliasingMode = v;
209   }
210 }
211
212 // =======================================================================
213 // function : SetImmediateModeDrawToFront
214 // purpose  :
215 // =======================================================================
216 Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
217 {
218   const Standard_Boolean aPrevMode = myTransientDrawToFront;
219   myTransientDrawToFront = theDrawToFrontBuffer;
220   return aPrevMode;
221 }
222
223 // =======================================================================
224 // function : ~OpenGl_Workspace
225 // purpose  :
226 // =======================================================================
227 OpenGl_Workspace::~OpenGl_Workspace()
228 {
229   if (!myLineAttribs.IsNull())
230   {
231     myLineAttribs.Nullify();
232     myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
233   }
234
235   ReleaseRaytraceResources();
236 }
237
238 // =======================================================================
239 // function : Activate
240 // purpose  :
241 // =======================================================================
242 Standard_Boolean OpenGl_Workspace::Activate()
243 {
244   if (!OpenGl_Window::Activate())
245     return Standard_False;
246
247   ViewMatrix_applied      = &myDefaultMatrix;
248   StructureMatrix_applied = &myDefaultMatrix;
249
250   ResetAppliedAspect();
251
252   return Standard_True;
253 }
254
255 // =======================================================================
256 // function : UseTransparency
257 // purpose  : call_togl_transparency
258 // =======================================================================
259 void OpenGl_Workspace::UseTransparency (const Standard_Boolean theFlag)
260 {
261   myUseTransparency = theFlag;
262 }
263
264 //=======================================================================
265 //function : ResetAppliedAspect
266 //purpose  : Sets default values of GL parameters in accordance with default aspects
267 //=======================================================================
268 void OpenGl_Workspace::ResetAppliedAspect()
269 {
270   NamedStatus           = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
271   HighlightColor        = &THE_WHITE_COLOR;
272   AspectLine_set        = &myDefaultAspectLine;
273   AspectLine_applied    = NULL;
274   AspectFace_set        = &myDefaultAspectFace;
275   AspectFace_applied    = NULL;
276   AspectMarker_set      = &myDefaultAspectMarker;
277   AspectMarker_applied  = NULL;
278   AspectText_set        = &myDefaultAspectText;
279   AspectText_applied    = NULL;
280   TextParam_set         = &myDefaultTextParam;
281   TextParam_applied     = NULL;
282   PolygonOffset_applied = THE_DEFAULT_POFFSET;
283   myCullingMode         = TelCullUndefined;
284
285   AspectLine(Standard_True);
286   AspectFace(Standard_True);
287   AspectMarker(Standard_True);
288   AspectText(Standard_True);
289 }
290
291 // =======================================================================
292 // function : DisableTexture
293 // purpose  :
294 // =======================================================================
295 Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
296 {
297   if (myTextureBound.IsNull())
298   {
299     return myTextureBound;
300   }
301
302 #if !defined(GL_ES_VERSION_2_0)
303   // reset texture matrix because some code may expect it is identity
304   GLint aMatrixMode = GL_TEXTURE;
305   glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
306   glMatrixMode (GL_TEXTURE);
307   glLoadIdentity();
308   glMatrixMode (aMatrixMode);
309 #endif
310
311   myTextureBound->Unbind (myGlContext);
312   switch (myTextureBound->GetTarget())
313   {
314   #if !defined(GL_ES_VERSION_2_0)
315     case GL_TEXTURE_1D:
316     {
317
318       if (myTextureBound->GetParams()->GenMode() != GL_NONE)
319       {
320         glDisable (GL_TEXTURE_GEN_S);
321       }
322       glDisable (GL_TEXTURE_1D);
323       break;
324     }
325   #endif
326     case GL_TEXTURE_2D:
327     {
328     #if !defined(GL_ES_VERSION_2_0)
329       if (myTextureBound->GetParams()->GenMode() != GL_NONE)
330       {
331         glDisable (GL_TEXTURE_GEN_S);
332         glDisable (GL_TEXTURE_GEN_T);
333         if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
334         {
335           glDisable (GL_POINT_SPRITE);
336         }
337       }
338     #endif
339       glDisable (GL_TEXTURE_2D);
340       break;
341     }
342     default: break;
343   }
344
345   Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
346   myTextureBound.Nullify();
347   return aPrevTexture;
348 }
349
350 // =======================================================================
351 // function : setTextureParams
352 // purpose  :
353 // =======================================================================
354 void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)&                theTexture,
355                                          const Handle(Graphic3d_TextureParams)& theParams)
356 {
357   const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
358   if (aParams.IsNull())
359   {
360     return;
361   }
362
363 #if !defined(GL_ES_VERSION_2_0)
364   GLint aMatrixMode = GL_TEXTURE;
365   glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
366
367   // setup texture matrix
368   glMatrixMode (GL_TEXTURE);
369   glLoadIdentity();
370   const Graphic3d_Vec2& aScale = aParams->Scale();
371   const Graphic3d_Vec2& aTrans = aParams->Translation();
372   glScalef     ( aScale.x(),  aScale.y(), 1.0f);
373   glTranslatef (-aTrans.x(), -aTrans.y(), 0.0f);
374   glRotatef (-aParams->Rotation(), 0.0f, 0.0f, 1.0f);
375
376   // setup generation of texture coordinates
377   switch (aParams->GenMode())
378   {
379     case Graphic3d_TOTM_OBJECT:
380     {
381       glTexGeni  (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
382       glTexGenfv (GL_S, GL_OBJECT_PLANE,     aParams->GenPlaneS().GetData());
383       if (theTexture->GetTarget() != GL_TEXTURE_1D)
384       {
385         glTexGeni  (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
386         glTexGenfv (GL_T, GL_OBJECT_PLANE,     aParams->GenPlaneT().GetData());
387       }
388       break;
389     }
390     case Graphic3d_TOTM_SPHERE:
391     {
392       glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
393       if (theTexture->GetTarget() != GL_TEXTURE_1D)
394       {
395         glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
396       }
397       break;
398     }
399     case Graphic3d_TOTM_EYE:
400     {
401       glMatrixMode (GL_MODELVIEW);
402       glPushMatrix();
403       glLoadIdentity();
404
405       glTexGeni  (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
406       glTexGenfv (GL_S, GL_EYE_PLANE,        aParams->GenPlaneS().GetData());
407
408       if (theTexture->GetTarget() != GL_TEXTURE_1D)
409       {
410         glTexGeni  (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
411         glTexGenfv (GL_T, GL_EYE_PLANE,        aParams->GenPlaneT().GetData());
412       }
413       glPopMatrix();
414       break;
415     }
416     case Graphic3d_TOTM_SPRITE:
417     {
418       if (GetGlContext()->core20 != NULL)
419       {
420         glEnable  (GL_POINT_SPRITE);
421         glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
422         glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
423         GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
424       }
425       break;
426     }
427     case Graphic3d_TOTM_MANUAL:
428     default: break;
429   }
430
431   // setup lighting
432   if (aParams->GenMode() != Graphic3d_TOTM_SPRITE)
433   {
434     glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aParams->IsModulate() ? GL_MODULATE : GL_DECAL);
435   }
436 #endif
437
438   // setup texture filtering and wrapping
439   //if (theTexture->GetParams() != theParams)
440   const GLenum aFilter   = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
441   const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
442   switch (theTexture->GetTarget())
443   {
444   #if !defined(GL_ES_VERSION_2_0)
445     case GL_TEXTURE_1D:
446     {
447       glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
448       glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
449       glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,     aWrapMode);
450       break;
451     }
452   #endif
453     case GL_TEXTURE_2D:
454     {
455       GLenum aFilterMin = aFilter;
456       if (theTexture->HasMipmaps())
457       {
458         aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
459         if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
460         {
461           aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
462         }
463         else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
464         {
465           aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
466         }
467
468         if (myGlContext->extAnis)
469         {
470           // setup degree of anisotropy filter
471           const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
472           switch (aParams->AnisoFilter())
473           {
474             case Graphic3d_LOTA_QUALITY:
475             {
476               glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aMaxDegree);
477               break;
478             }
479             case Graphic3d_LOTA_MIDDLE:
480             {
481
482               glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2));
483               break;
484             }
485             case Graphic3d_LOTA_FAST:
486             {
487               glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2);
488               break;
489             }
490             case Graphic3d_LOTA_OFF:
491             default:
492             {
493               glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
494               break;
495             }
496           }
497         }
498       }
499       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
500       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
501       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     aWrapMode);
502       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     aWrapMode);
503       break;
504     }
505     default: break;
506   }
507
508   switch (theTexture->GetTarget())
509   {
510   #if !defined(GL_ES_VERSION_2_0)
511     case GL_TEXTURE_1D:
512     {
513       if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
514       {
515         glEnable (GL_TEXTURE_GEN_S);
516       }
517       glEnable (GL_TEXTURE_1D);
518       break;
519     }
520   #endif
521     case GL_TEXTURE_2D:
522     {
523     #if !defined(GL_ES_VERSION_2_0)
524       if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
525       {
526         glEnable (GL_TEXTURE_GEN_S);
527         glEnable (GL_TEXTURE_GEN_T);
528       }
529     #endif
530       glEnable (GL_TEXTURE_2D);
531       break;
532     }
533     default: break;
534   }
535
536 #if !defined(GL_ES_VERSION_2_0)
537   glMatrixMode (aMatrixMode); // turn back active matrix
538 #endif
539   theTexture->SetParams (aParams);
540 }
541
542 // =======================================================================
543 // function : EnableTexture
544 // purpose  :
545 // =======================================================================
546 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)&          theTexture,
547                                                         const Handle(Graphic3d_TextureParams)& theParams)
548 {
549   if (theTexture.IsNull() || !theTexture->IsValid())
550   {
551     return DisableTexture();
552   }
553
554   if (myTextureBound == theTexture
555    && (theParams.IsNull() || theParams == theTexture->GetParams()))
556   {
557     // already bound
558     return myTextureBound;
559   }
560
561   Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
562   myTextureBound = theTexture;
563   myTextureBound->Bind (myGlContext);
564   setTextureParams (myTextureBound, theParams);
565
566   return aPrevTexture;
567 }
568
569 // =======================================================================
570 // function : Redraw
571 // purpose  :
572 // =======================================================================
573 void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
574                                const Aspect_CLayer2d& theCUnderLayer,
575                                const Aspect_CLayer2d& theCOverLayer)
576 {
577   if (!Activate())
578   {
579     return;
580   }
581
582   ++myFrameCounter;
583   myIsCullingEnabled = theCView.IsCullingEnabled;
584
585   // release pending GL resources
586   Handle(OpenGl_Context) aGlCtx = GetGlContext();
587   aGlCtx->ReleaseDelayed();
588
589   // fetch OpenGl context state
590   aGlCtx->FetchState();
591
592   Tint toSwap = (aGlCtx->IsRender()); // swap buffers
593   GLint aViewPortBack[4];
594   OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
595   if (aFrameBuffer != NULL)
596   {
597     glGetIntegerv (GL_VIEWPORT, aViewPortBack);
598     aFrameBuffer->SetupViewport (aGlCtx);
599     toSwap = 0; // no need to swap buffers
600   }
601
602   myToRedrawGL = Standard_True;
603   if (theCView.RenderParams.Method == Graphic3d_RM_RAYTRACING
604    && myComputeInitStatus != OpenGl_RT_FAIL)
605   {
606     if (UpdateRaytraceGeometry (OpenGl_GUM_CHECK) && myIsRaytraceDataValid)
607     {
608       myToRedrawGL = Standard_False;
609
610       // Only non-raytracable structures should be rendered in OpenGL mode.
611       Handle(OpenGl_RenderFilter) aRenderFilter = GetRenderFilter();
612       myRaytraceFilter->SetPrevRenderFilter (aRenderFilter);
613       SetRenderFilter (myRaytraceFilter);
614
615       Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
616       Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
617
618       if (myOpenGlFBO.IsNull())
619       {
620         myOpenGlFBO = new OpenGl_FrameBuffer();
621       }
622       if (myOpenGlFBO->GetVPSizeX() != aSizeX
623        || myOpenGlFBO->GetVPSizeY() != aSizeY)
624       {
625         myOpenGlFBO->Init (aGlCtx, aSizeX, aSizeY);
626       }
627
628       // OverLayer and UnderLayer shouldn't be drawn by OpenGL.
629       // They will be drawn during ray-tracing.
630       Aspect_CLayer2d anEmptyCLayer;
631       anEmptyCLayer.ptrLayer = NULL;
632
633       myOpenGlFBO->BindBuffer (aGlCtx);
634       redraw1 (theCView, anEmptyCLayer, anEmptyCLayer, 0);
635       myOpenGlFBO->UnbindBuffer (aGlCtx);
636
637       const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
638       Raytrace (theCView, aSizeX, aSizeY, isImmediate ? 0 : toSwap,
639                 theCOverLayer, theCUnderLayer, aFrameBuffer);
640
641       if (isImmediate)
642       {
643         RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
644       }
645
646       SetRenderFilter (aRenderFilter);
647
648       theCView.WasRedrawnGL = Standard_False;
649     }
650   }
651
652   if (myToRedrawGL)
653   {
654     // draw entire frame using normal OpenGL pipeline
655     if (aFrameBuffer != NULL)
656     {
657       aFrameBuffer->BindBuffer (aGlCtx);
658     }
659
660     const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
661     redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap);
662     if (isImmediate)
663     {
664       RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
665     }
666
667     theCView.WasRedrawnGL = Standard_True;
668   }
669
670   if (aFrameBuffer != NULL)
671   {
672     aFrameBuffer->UnbindBuffer (aGlCtx);
673     // move back original viewport
674     glViewport (aViewPortBack[0], aViewPortBack[1], aViewPortBack[2], aViewPortBack[3]);
675   }
676
677 #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
678   if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow))
679   {
680     GLint params[4];
681     glGetIntegerv (GL_VIEWPORT, params);
682     int nWidth  = params[2] & ~0x7;
683     int nHeight = params[3] & ~0x7;
684
685     const int nBitsPerPixel = 24;
686     GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
687
688     glPixelStorei (GL_PACK_ALIGNMENT, 1);
689     glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
690     OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
691     delete[] aDumpData;
692   }
693 #endif
694
695   // reset render mode state
696   aGlCtx->FetchState();
697 }
698
699 // =======================================================================
700 // function : redraw1
701 // purpose  :
702 // =======================================================================
703 void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
704                                 const Aspect_CLayer2d& theCUnderLayer,
705                                 const Aspect_CLayer2d& theCOverLayer,
706                                 const int              theToSwap)
707 {
708   if (myView.IsNull())
709   {
710     return;
711   }
712
713   // request reset of material
714   NamedStatus |= OPENGL_NS_RESMAT;
715
716   GLbitfield toClear = GL_COLOR_BUFFER_BIT;
717   if (myUseZBuffer)
718   {
719     glDepthFunc (GL_LEQUAL);
720     glDepthMask (GL_TRUE);
721     if (myUseDepthTest)
722     {
723       glEnable (GL_DEPTH_TEST);
724     }
725     else
726     {
727       glDisable (GL_DEPTH_TEST);
728     }
729
730   #if !defined(GL_ES_VERSION_2_0)
731     glClearDepth (1.0);
732   #else
733     glClearDepthf (1.0f);
734   #endif
735     toClear |= GL_DEPTH_BUFFER_BIT;
736   }
737   else
738   {
739     glDisable (GL_DEPTH_TEST);
740   }
741
742   if (!ToRedrawGL())
743   {
744     // set background to black
745     glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
746     toClear |= GL_DEPTH_BUFFER_BIT; //
747   }
748   else
749   {
750     if (NamedStatus & OPENGL_NS_WHITEBACK)
751     {
752         // set background to white
753       glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
754       toClear |= GL_DEPTH_BUFFER_BIT;
755     }
756     else
757     {
758       glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
759     }
760   }
761   glClear (toClear);
762
763   Handle(OpenGl_Workspace) aWS (this);
764   myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer);
765
766   // swap the buffers
767   if (theToSwap)
768   {
769     GetGlContext()->SwapBuffers();
770     myBackBufferRestored = Standard_False;
771     myIsImmediateDrawn   = Standard_False;
772   }
773   else
774   {
775     glFlush(); //
776     myBackBufferRestored = Standard_True;//
777     myIsImmediateDrawn   = Standard_False;//
778   }
779 }
780
781 // =======================================================================
782 // function : copyBackToFront
783 // purpose  :
784 // =======================================================================
785 void OpenGl_Workspace::copyBackToFront()
786 {
787 #if !defined(GL_ES_VERSION_2_0)
788   glMatrixMode (GL_PROJECTION);
789   glPushMatrix();
790   glLoadIdentity();
791   gluOrtho2D (0.0, (GLdouble )myWidth, 0.0, (GLdouble )myHeight);
792
793   glMatrixMode (GL_MODELVIEW);
794   glPushMatrix();
795   glLoadIdentity();
796
797   DisableFeatures();
798
799   glDrawBuffer (GL_FRONT);
800   glReadBuffer (GL_BACK);
801
802   glRasterPos2i (0, 0);
803   glCopyPixels  (0, 0, myWidth + 1, myHeight + 1, GL_COLOR);
804
805   EnableFeatures();
806
807   glMatrixMode (GL_PROJECTION);
808   glPopMatrix();
809   glMatrixMode (GL_MODELVIEW);
810   glPopMatrix();
811
812   glDrawBuffer (GL_BACK);
813
814 #endif
815   myIsImmediateDrawn = Standard_False;
816 }
817
818 // =======================================================================
819 // function : DisplayCallback
820 // purpose  :
821 // =======================================================================
822 void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
823                                         Standard_Integer       theReason)
824 {
825   if (theCView.GDisplayCB == NULL)
826   {
827     return;
828   }
829
830   Aspect_GraphicCallbackStruct aCallData;
831   aCallData.reason    = theReason;
832   aCallData.glContext = GetGlContext();
833   aCallData.wsID      = theCView.WsId;
834   aCallData.viewID    = theCView.ViewId;
835   theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
836 }
837
838 // =======================================================================
839 // function : RedrawImmediate
840 // purpose  :
841 // =======================================================================
842 void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
843                                         const Aspect_CLayer2d& theCUnderLayer,
844                                         const Aspect_CLayer2d& theCOverLayer,
845                                         const Standard_Boolean theToForce)
846 {
847   if (!Activate())
848   {
849     return;
850   }
851
852   GLboolean isDoubleBuffer = GL_FALSE;
853 #if !defined(GL_ES_VERSION_2_0)
854   glGetBooleanv (GL_DOUBLEBUFFER, &isDoubleBuffer);
855 #endif
856   if (myView->ImmediateStructures().IsEmpty())
857   {
858     if (theToForce
859      || !myIsImmediateDrawn)
860     {
861       myIsImmediateDrawn = Standard_False;
862       return;
863     }
864
865     if (myBackBufferRestored
866      && isDoubleBuffer)
867     {
868       copyBackToFront();
869       glFlush();
870     }
871     else
872     {
873       Redraw (theCView, theCUnderLayer, theCOverLayer);
874     }
875     return;
876   }
877
878   if (isDoubleBuffer && myTransientDrawToFront)
879   {
880     if (!myBackBufferRestored)
881     {
882       Redraw (theCView, theCUnderLayer, theCOverLayer);
883       return;
884     }
885     copyBackToFront();
886     MakeFrontBufCurrent();
887   }
888   else
889   {
890     myBackBufferRestored = Standard_False;
891   }
892   myIsImmediateDrawn = Standard_True;
893
894   NamedStatus |= OPENGL_NS_IMMEDIATE;
895   ///glDisable (GL_LIGHTING);
896   glDisable (GL_DEPTH_TEST);
897
898   Handle(OpenGl_Workspace) aWS (this);
899   for (OpenGl_SequenceOfStructure::Iterator anIter (myView->ImmediateStructures());
900        anIter.More(); anIter.Next())
901   {
902     const OpenGl_Structure* aStructure = anIter.Value();
903     aStructure->Render (aWS);
904   }
905
906   NamedStatus &= ~OPENGL_NS_IMMEDIATE;
907
908   if (isDoubleBuffer && myTransientDrawToFront)
909   {
910     glFlush();
911     MakeBackBufCurrent();
912   }
913 }