0025885: Visualization, ray tracing - Improve layer processing
[occt.git] / src / OpenGl / OpenGl_View_2.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 <stdio.h>
17 #include <stdlib.h>
18
19 #include <OpenGl_GlCore11.hxx>
20 #include <OpenGl_tgl_funcs.hxx>
21
22 #include <Graphic3d_TextureParams.hxx>
23 #include <Graphic3d_Texture2Dmanual.hxx>
24 #include <Image_AlienPixMap.hxx>
25 #include <Visual3d_Layer.hxx>
26
27 #include <NCollection_Mat4.hxx>
28
29 #include <OpenGl_AspectLine.hxx>
30 #include <OpenGl_Context.hxx>
31 #include <OpenGl_Matrix.hxx>
32 #include <OpenGl_Workspace.hxx>
33 #include <OpenGl_View.hxx>
34 #include <OpenGl_Trihedron.hxx>
35 #include <OpenGl_GraduatedTrihedron.hxx>
36 #include <OpenGl_PrimitiveArray.hxx>
37 #include <OpenGl_PrinterContext.hxx>
38 #include <OpenGl_ShaderManager.hxx>
39 #include <OpenGl_ShaderProgram.hxx>
40 #include <OpenGl_Structure.hxx>
41 #include <OpenGl_ArbFBO.hxx>
42
43 #define EPSI 0.0001
44
45 namespace
46 {
47
48   static const GLfloat THE_DEFAULT_AMBIENT[4]    = { 0.0f, 0.0f, 0.0f, 1.0f };
49   static const GLfloat THE_DEFAULT_SPOT_DIR[3]   = { 0.0f, 0.0f, -1.0f };
50   static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
51   static const GLfloat THE_DEFAULT_SPOT_CUTOFF   = 180.0f;
52
53 };
54
55 extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
56
57 /*----------------------------------------------------------------------*/
58
59 struct OPENGL_CLIP_PLANE
60 {
61   GLboolean isEnabled;
62   GLdouble Equation[4];
63   DEFINE_STANDARD_ALLOC
64 };
65
66 /*----------------------------------------------------------------------*/
67 /*
68 * Fonctions privees
69 */
70
71 #if !defined(GL_ES_VERSION_2_0)
72 /*-----------------------------------------------------------------*/
73 /*
74 *  Set des lumieres
75 */
76 static void bindLight (const OpenGl_Light&             theLight,
77                        GLenum&                         theLightGlId,
78                        Graphic3d_Vec4&                 theAmbientColor,
79                        const Handle(OpenGl_Workspace)& theWorkspace)
80 {
81   // Only 8 lights in OpenGL...
82   if (theLightGlId > GL_LIGHT7)
83   {
84     return;
85   }
86
87   if (theLight.Type == Visual3d_TOLS_AMBIENT)
88   {
89     // add RGBA intensity of the ambient light
90     theAmbientColor += theLight.Color;
91     return;
92   }
93
94   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
95
96   // the light is a headlight?
97   if (theLight.IsHeadlight)
98   {
99
100     aContext->WorldViewState.Push();
101     aContext->WorldViewState.SetIdentity();
102
103     aContext->ApplyWorldViewMatrix();
104   }
105
106   // setup light type
107   switch (theLight.Type)
108   {
109     case Visual3d_TOLS_DIRECTIONAL:
110     {
111       // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
112       const OpenGl_Vec4 anInfDir = -theLight.Direction;
113
114       // to create a realistic effect,  set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
115       glLightfv (theLightGlId, GL_AMBIENT,               THE_DEFAULT_AMBIENT);
116       glLightfv (theLightGlId, GL_DIFFUSE,               theLight.Color.GetData());
117       glLightfv (theLightGlId, GL_SPECULAR,              theLight.Color.GetData());
118       glLightfv (theLightGlId, GL_POSITION,              anInfDir.GetData());
119       glLightfv (theLightGlId, GL_SPOT_DIRECTION,        THE_DEFAULT_SPOT_DIR);
120       glLightf  (theLightGlId, GL_SPOT_EXPONENT,         THE_DEFAULT_SPOT_EXPONENT);
121       glLightf  (theLightGlId, GL_SPOT_CUTOFF,           THE_DEFAULT_SPOT_CUTOFF);
122       break;
123     }
124     case Visual3d_TOLS_POSITIONAL:
125     {
126       // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
127       glLightfv (theLightGlId, GL_AMBIENT,               THE_DEFAULT_AMBIENT);
128       glLightfv (theLightGlId, GL_DIFFUSE,               theLight.Color.GetData());
129       glLightfv (theLightGlId, GL_SPECULAR,              theLight.Color.GetData());
130       glLightfv (theLightGlId, GL_POSITION,              theLight.Position.GetData());
131       glLightfv (theLightGlId, GL_SPOT_DIRECTION,        THE_DEFAULT_SPOT_DIR);
132       glLightf  (theLightGlId, GL_SPOT_EXPONENT,         THE_DEFAULT_SPOT_EXPONENT);
133       glLightf  (theLightGlId, GL_SPOT_CUTOFF,           THE_DEFAULT_SPOT_CUTOFF);
134       glLightf  (theLightGlId, GL_CONSTANT_ATTENUATION,  theLight.ConstAttenuation());
135       glLightf  (theLightGlId, GL_LINEAR_ATTENUATION,    theLight.LinearAttenuation());
136       glLightf  (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
137       break;
138     }
139     case Visual3d_TOLS_SPOT:
140     {
141       glLightfv (theLightGlId, GL_AMBIENT,               THE_DEFAULT_AMBIENT);
142       glLightfv (theLightGlId, GL_DIFFUSE,               theLight.Color.GetData());
143       glLightfv (theLightGlId, GL_SPECULAR,              theLight.Color.GetData());
144       glLightfv (theLightGlId, GL_POSITION,              theLight.Position.GetData());
145       glLightfv (theLightGlId, GL_SPOT_DIRECTION,        theLight.Direction.GetData());
146       glLightf  (theLightGlId, GL_SPOT_EXPONENT,         theLight.Concentration() * 128.0f);
147       glLightf  (theLightGlId, GL_SPOT_CUTOFF,          (theLight.Angle() * 180.0f) / GLfloat(M_PI));
148       glLightf  (theLightGlId, GL_CONSTANT_ATTENUATION,  theLight.ConstAttenuation());
149       glLightf  (theLightGlId, GL_LINEAR_ATTENUATION,    theLight.LinearAttenuation());
150       glLightf  (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
151       break;
152     }
153   }
154
155   // restore matrix in case of headlight
156   if (theLight.IsHeadlight)
157   {
158     aContext->WorldViewState.Pop();
159   }
160
161   glEnable (theLightGlId++);
162 }
163 #endif
164
165 /*----------------------------------------------------------------------*/
166
167 void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
168 {
169   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
170
171   if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background
172     || (!myBgTextureArray->IsDefined()                       // no texture
173      && !myBgGradientArray->IsDefined()))                    // no gradient
174   {
175     return;
176   }
177
178   aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
179
180   aCtx->WorldViewState.Push();
181   aCtx->ProjectionState.Push();
182   aCtx->WorldViewState.SetIdentity();
183   aCtx->ProjectionState.SetIdentity();
184   aCtx->ApplyProjectionMatrix();
185   aCtx->ApplyWorldViewMatrix();
186
187   // Drawing background gradient if:
188   // - gradient fill type is not Aspect_GFM_NONE and
189   // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
190   if (myBgGradientArray->IsDefined()
191     && (!myTextureParams->DoTextureMap()
192       || myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED
193       || myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE))
194   {
195   #if !defined(GL_ES_VERSION_2_0)
196     GLint aShadingModelOld = GL_SMOOTH;
197     if (aCtx->core11 != NULL)
198     {
199       aCtx->core11fwd->glDisable (GL_LIGHTING);
200       aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld);
201       aCtx->core11->glShadeModel (GL_SMOOTH);
202     }
203   #endif
204
205     if (myBgGradientArray->IsDataChanged())
206     {
207       myBgGradientArray->Init (theWorkspace);
208     }
209
210     myBgGradientArray->Render (theWorkspace);
211
212   #if !defined(GL_ES_VERSION_2_0)
213     if (aCtx->core11 != NULL)
214     {
215       aCtx->core11->glShadeModel (aShadingModelOld);
216     }
217   #endif
218   }
219
220   // Drawing background image if it is defined
221   // (texture is defined and fill type is not Aspect_FM_NONE)
222   if (myBgTextureArray->IsDefined()
223    && myTextureParams->DoTextureMap())
224   {
225     aCtx->core11fwd->glDisable (GL_BLEND);
226
227     const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams);
228
229     if (myBgTextureArray->IsDataChanged()
230      || myBgTextureArray->IsViewSizeChanged (theWorkspace))
231     {
232       myBgTextureArray->Init (theWorkspace);
233     }
234
235     myBgTextureArray->Render (theWorkspace);
236
237     // restore aspects
238     theWorkspace->SetAspectFace (anOldAspectFace);
239   }
240
241   aCtx->WorldViewState.Pop();
242   aCtx->ProjectionState.Pop();
243   aCtx->ApplyProjectionMatrix();
244
245   if (theWorkspace->UseZBuffer())
246   {
247     aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
248   }
249 }
250
251 /*----------------------------------------------------------------------*/
252
253 //call_func_redraw_all_structs_proc
254 void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
255                           const Handle(OpenGl_Workspace)&      theWorkspace,
256                           const Graphic3d_CView&               theCView,
257                           const Aspect_CLayer2d&               theCUnderLayer,
258                           const Aspect_CLayer2d&               theCOverLayer,
259                           const Standard_Boolean               theToDrawImmediate)
260 {
261   // ==================================
262   //      Step 1: Prepare for redraw
263   // ==================================
264
265   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
266
267 #if !defined(GL_ES_VERSION_2_0)
268   // store and disable current clipping planes
269   const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
270   NCollection_Array1<OPENGL_CLIP_PLANE> aOldPlanes (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + aMaxPlanes - 1);
271   if (aContext->core11 != NULL)
272   {
273     for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
274     {
275       OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
276       aContext->core11->glGetClipPlane (aClipPlaneId, aPlane.Equation);
277       if (aPlane.isEnabled)
278       {
279         aContext->core11fwd->glDisable (aClipPlaneId);
280         aPlane.isEnabled = GL_TRUE;
281       }
282       else
283       {
284         aPlane.isEnabled = GL_FALSE;
285       }
286     }
287   }
288 #endif
289
290   // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
291   Standard_Boolean isProjectionMatUpdateNeeded  = Standard_False;
292   Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
293   if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
294   {
295     isProjectionMatUpdateNeeded = Standard_True;
296     myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState();
297   }
298   if (myBVHSelector.ModelViewState() != myCamera->ModelViewState())
299   {
300     isOrientationMatUpdateNeeded = Standard_True;
301     myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
302   }
303
304   if (isProjectionMatUpdateNeeded
305    || isOrientationMatUpdateNeeded)
306   {
307     myBVHSelector.SetViewVolume (myCamera);
308   }
309
310   const Handle(OpenGl_ShaderManager)& aManager   = aContext->ShaderManager();
311   const Standard_Boolean              isSameView = aManager->IsSameView (this); // force camera state update when needed
312   if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
313   {
314     aManager->UpdateLightSourceStateTo (&myLights);
315     myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
316   }
317
318   if (myProjectionState != myCamera->ProjectionState()
319   || !isSameView)
320   {
321     myProjectionState = myCamera->ProjectionState();
322     aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
323     aContext->ApplyProjectionMatrix();
324   }
325
326   if (myModelViewState != myCamera->ModelViewState()
327   || !isSameView)
328   {
329     myModelViewState = myCamera->ModelViewState();
330     aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF());
331     aContext->ApplyWorldViewMatrix();
332   }
333
334   if (aManager->ModelWorldState().Index() == 0)
335   {
336     aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
337   }
338
339   // ====================================
340   //      Step 2: Redraw background
341   // ====================================
342
343   // Render background
344   if (!theToDrawImmediate)
345   {
346     DrawBackground (theWorkspace);
347   }
348
349 #if !defined(GL_ES_VERSION_2_0)
350   // Switch off lighting by default
351   if (aContext->core11 != NULL)
352   {
353     glDisable(GL_LIGHTING);
354   }
355 #endif
356
357   // =================================
358   //      Step 3: Draw underlayer
359   // =================================
360   if (!theToDrawImmediate)
361   {
362     RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCUnderLayer);
363   }
364
365   // =================================
366   //      Step 4: Redraw main plane
367   // =================================
368
369   // Setup face culling
370   GLboolean isCullFace = GL_FALSE;
371   if ( myBackfacing )
372   {
373     isCullFace = glIsEnabled( GL_CULL_FACE );
374     if ( myBackfacing < 0 )
375     {
376       glEnable( GL_CULL_FACE );
377       glCullFace( GL_BACK );
378     }
379     else
380       glDisable( GL_CULL_FACE );
381   }
382
383 #if !defined(GL_ES_VERSION_2_0)
384   // if the view is scaled normal vectors are scaled to unit
385   // length for correct displaying of shaded objects
386   const gp_Pnt anAxialScale = myCamera->AxialScale();
387   if (anAxialScale.X() != 1.F ||
388       anAxialScale.Y() != 1.F ||
389       anAxialScale.Z() != 1.F)
390   {
391     aContext->SetGlNormalizeEnabled (Standard_True);
392   }
393   else
394   {
395     aContext->SetGlNormalizeEnabled (Standard_False);
396   }
397
398   // Apply Fog
399   if (myFog.IsOn
400    && aContext->core11 != NULL)
401   {
402     Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
403     if (myCamera->ZFar() < aFogFrontConverted)
404     {
405       aFogFrontConverted = myCamera->ZFar();
406       myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
407     }
408
409     Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
410     if (myCamera->ZFar() < aFogFrontConverted)
411     {
412       aFogBackConverted = myCamera->ZFar();
413       myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
414     }
415
416     if (aFogFrontConverted > aFogBackConverted)
417     {
418       myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
419       myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
420     }
421
422     glFogi(GL_FOG_MODE, GL_LINEAR);
423     glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
424     glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
425     glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
426     glEnable(GL_FOG);
427   }
428   else if (aContext->core11 != NULL)
429   {
430     glDisable (GL_FOG);
431   }
432
433   // Apply InteriorShadingMethod
434   if (aContext->core11 != NULL)
435   {
436     aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET
437                                  || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH);
438   }
439 #endif
440
441   aManager->SetShadingModel (myShadingModel);
442
443   // Apply AntiAliasing
444   if (myAntiAliasing)
445     theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
446   else
447     theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
448
449   if (!aManager->IsEmpty())
450   {
451     aManager->UpdateClippingState();
452   }
453
454   // Redraw 3d scene
455   if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
456   {
457     // single-pass monographic rendering
458     // redraw scene with normal orientation and projection
459     RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
460   }
461   else
462   {
463     // two stereographic passes
464
465     // safely switch to left Eye buffer
466     aContext->SetDrawBufferLeft();
467
468     aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF());
469     aContext->ApplyProjectionMatrix();
470
471     // redraw left Eye
472     RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
473
474     // reset depth buffer of first rendering pass
475     if (theWorkspace->UseDepthTest())
476     {
477       glClear (GL_DEPTH_BUFFER_BIT);
478     }
479     // safely switch to right Eye buffer
480     aContext->SetDrawBufferRight();
481
482     aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF());
483     aContext->ApplyProjectionMatrix();
484
485     // redraw right Eye
486     RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
487
488     // switch back to monographic rendering
489     aContext->SetDrawBufferMono();
490   }
491
492   // ===============================
493   //      Step 5: Trihedron
494   // ===============================
495
496   // Resetting GL parameters according to the default aspects
497   // in order to synchronize GL state with the graphic driver state
498   // before drawing auxiliary stuff (trihedrons, overlayer)
499   // and invoking optional callbacks
500   theWorkspace->ResetAppliedAspect();
501
502   aContext->ChangeClipping().RemoveAll();
503
504   if (!aManager->IsEmpty())
505   {
506     aManager->ResetMaterialStates();
507     aManager->RevertClippingState();
508
509     // We need to disable (unbind) all shaders programs to ensure
510     // that all objects without specified aspect will be drawn
511     // correctly (such as background)
512     aContext->BindProgram (NULL);
513   }
514
515   // Render trihedron
516   if (!theToDrawImmediate)
517   {
518     RedrawTrihedron (theWorkspace);
519
520     // Restore face culling
521     if ( myBackfacing )
522     {
523       if ( isCullFace )
524       {
525         glEnable   ( GL_CULL_FACE );
526         glCullFace ( GL_BACK      );
527       }
528       else
529         glDisable ( GL_CULL_FACE );
530     }
531   }
532
533   // ===============================
534   //      Step 6: Redraw overlay
535   // ===============================
536   if (!theToDrawImmediate)
537   {
538     const int aMode = 0;
539     theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
540
541     RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer);
542
543     theWorkspace->DisplayCallback (theCView, aMode);
544   }
545
546   // ===============================
547   //      Step 7: Finalize
548   // ===============================
549
550 #if !defined(GL_ES_VERSION_2_0)
551   // restore clipping planes
552   if (aContext->core11 != NULL)
553   {
554     for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
555     {
556       const OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
557       aContext->core11->glClipPlane (aClipPlaneId, aPlane.Equation);
558       if (aPlane.isEnabled)
559         aContext->core11fwd->glEnable (aClipPlaneId);
560       else
561         aContext->core11fwd->glDisable (aClipPlaneId);
562     }
563   }
564 #endif
565
566   // ==============================================================
567   //      Step 8: Keep shader manager informed about last View
568   // ==============================================================
569
570   if (!aManager.IsNull())
571   {
572     aManager->SetLastView (this);
573   }
574 }
575
576 // =======================================================================
577 // function : InvalidateBVHData
578 // purpose  :
579 // =======================================================================
580 void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
581 {
582   myZLayers.InvalidateBVHData (theLayerId);
583 }
584
585 /*----------------------------------------------------------------------*/
586
587 //ExecuteViewDisplay
588 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& theWorkspace,
589                                  const Graphic3d_CView&          theCView,
590                                  const Standard_Boolean          theToDrawImmediate)
591 {
592   if ( myZLayers.NbStructures() <= 0 )
593     return;
594
595   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
596
597   if ( (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
598   {
599   #if !defined(GL_ES_VERSION_2_0)
600     const int anAntiAliasingMode = theWorkspace->AntiAliasingMode();
601   #endif
602
603     if ( !myAntiAliasing )
604     {
605     #if !defined(GL_ES_VERSION_2_0)
606       if (aCtx->core11 != NULL)
607       {
608         glDisable (GL_POINT_SMOOTH);
609       }
610       glDisable(GL_LINE_SMOOTH);
611       if( anAntiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
612     #endif
613       glBlendFunc (GL_ONE, GL_ZERO);
614       glDisable (GL_BLEND);
615     }
616     else
617     {
618     #if !defined(GL_ES_VERSION_2_0)
619       if (aCtx->core11 != NULL)
620       {
621         glEnable(GL_POINT_SMOOTH);
622       }
623       glEnable(GL_LINE_SMOOTH);
624       if( anAntiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
625     #endif
626       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
627       glEnable (GL_BLEND);
628     }
629   }
630
631   Standard_Boolean toRenderGL = theToDrawImmediate ||
632     theCView.RenderParams.Method != Graphic3d_RM_RAYTRACING || myRaytraceInitStatus == OpenGl_RT_FAIL;
633
634   if (!toRenderGL)
635   {
636     toRenderGL = !initRaytraceResources (theCView, aCtx) ||
637       !updateRaytraceGeometry (OpenGl_GUM_CHECK, theWorkspace->ActiveViewId(), aCtx);
638
639     OpenGl_FrameBuffer* anOutputFBO = NULL;
640
641     if (theWorkspace->ResultFBO()->IsValid())
642     {
643       anOutputFBO = theWorkspace->ResultFBO().operator->();
644     }
645     else if (theCView.ptrFBO != NULL)
646     {
647       anOutputFBO = (OpenGl_FrameBuffer* )theCView.ptrFBO;
648     }
649     else
650     {
651       //toRenderGL = Standard_True; // failed to get valid FBO
652     }
653
654     if (!toRenderGL && myIsRaytraceDataValid)
655     {
656       const Standard_Integer aSizeX = anOutputFBO != NULL ?
657         anOutputFBO->GetVPSizeX() : theWorkspace->Width();
658       const Standard_Integer aSizeY = anOutputFBO != NULL ?
659         anOutputFBO->GetVPSizeY() : theWorkspace->Height();
660
661       if (myOpenGlFBO.IsNull())
662         myOpenGlFBO = new OpenGl_FrameBuffer;
663
664       if (myOpenGlFBO->GetVPSizeX() != aSizeX
665        || myOpenGlFBO->GetVPSizeY() != aSizeY)
666       {
667         myOpenGlFBO->Init (aCtx, aSizeX, aSizeY);
668       }
669
670       if (myRaytraceFilter.IsNull())
671         myRaytraceFilter = new OpenGl_RaytraceFilter;
672
673       myRaytraceFilter->SetPrevRenderFilter (theWorkspace->GetRenderFilter());
674
675       if (anOutputFBO != NULL)
676         anOutputFBO->UnbindBuffer (aCtx);
677
678       // Prepare preliminary OpenGL output
679       if (aCtx->arbFBOBlit != NULL)
680       {
681         // Render bottom OSD layer
682         myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Bottom);
683
684         theWorkspace->SetRenderFilter (myRaytraceFilter);
685         {
686           if (anOutputFBO != NULL)
687           {
688             anOutputFBO->BindReadBuffer (aCtx);
689           }
690           else
691           {
692             aCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
693           }
694
695           myOpenGlFBO->BindDrawBuffer (aCtx);
696
697           aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, aSizeX, aSizeY,
698                                                0, 0, aSizeX, aSizeY,
699                                                GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
700                                                GL_NEAREST);
701
702           // Render non-polygonal elements in default layer
703           myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Default);
704         }
705         theWorkspace->SetRenderFilter (myRaytraceFilter->PrevRenderFilter());
706       }
707
708       if (anOutputFBO != NULL)
709       {
710         anOutputFBO->BindBuffer (aCtx);
711       }
712       else
713       {
714         aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, 0);
715       }
716
717       // Ray-tracing polygonal primitive arrays
718       raytrace (theCView, aSizeX, aSizeY, anOutputFBO, aCtx);
719
720       // Render upper (top and topmost) OpenGL layers
721       myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Upper);
722     }
723   }
724
725   // Redraw 3D scene using OpenGL in standard
726   // mode or in case of ray-tracing failure
727   if (toRenderGL)
728   {
729     myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_All);
730
731     // Set flag that scene was redrawn by standard pipeline
732     theCView.WasRedrawnGL = Standard_True;
733   }
734 }
735
736 /*----------------------------------------------------------------------*/
737
738 //call_togl_redraw_layer2d
739 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
740                                  const Handle(OpenGl_Workspace)&      theWorkspace,
741                                  const Graphic3d_CView&               /*ACView*/,
742                                  const Aspect_CLayer2d&               ACLayer)
743 {
744 #if !defined(GL_ES_VERSION_2_0)
745   if (&ACLayer == NULL
746    || ACLayer.ptrLayer == NULL
747    || ACLayer.ptrLayer->listIndex == 0) return;
748
749   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
750   if (aContext->core11 == NULL)
751   {
752     return;
753   }
754
755   GLsizei dispWidth  = (GLsizei )ACLayer.viewport[0];
756   GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
757
758   aContext->WorldViewState.Push();
759   aContext->ProjectionState.Push();
760
761   aContext->WorldViewState.SetIdentity();
762   aContext->ProjectionState.SetIdentity();
763
764   aContext->ApplyWorldViewMatrix();
765   aContext->ApplyProjectionMatrix();
766
767   if (!ACLayer.sizeDependent)
768     aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight);
769
770   float left = ACLayer.ortho[0];
771   float right = ACLayer.ortho[1];
772   float bottom = ACLayer.ortho[2];
773   float top = ACLayer.ortho[3];
774
775   int attach = ACLayer.attach;
776
777   const float ratio = !ACLayer.sizeDependent
778                     ? float(dispWidth) / float(dispHeight)
779                     : float(theWorkspace->Width()) / float(theWorkspace->Height());
780
781   float delta;
782   if (ratio >= 1.0) {
783     delta = (float )((top - bottom)/2.0);
784     switch (attach) {
785       case 0: /* Aspect_TOC_BOTTOM_LEFT */
786         top = bottom + 2*delta/ratio;
787         break;
788       case 1: /* Aspect_TOC_BOTTOM_RIGHT */
789         top = bottom + 2*delta/ratio;
790         break;
791       case 2: /* Aspect_TOC_TOP_LEFT */
792         bottom = top - 2*delta/ratio;
793         break;
794       case 3: /* Aspect_TOC_TOP_RIGHT */
795         bottom = top - 2*delta/ratio;
796         break;
797     }
798   }
799   else {
800     delta = (float )((right - left)/2.0);
801     switch (attach) {
802       case 0: /* Aspect_TOC_BOTTOM_LEFT */
803         right = left + 2*delta*ratio;
804         break;
805       case 1: /* Aspect_TOC_BOTTOM_RIGHT */
806         left = right - 2*delta*ratio;
807         break;
808       case 2: /* Aspect_TOC_TOP_LEFT */
809         right = left + 2*delta*ratio;
810         break;
811       case 3: /* Aspect_TOC_TOP_RIGHT */
812         left = right - 2*delta*ratio;
813         break;
814     }
815   }
816
817 #ifdef _WIN32
818   // Check printer context that exists only for print operation
819   if (!thePrintContext.IsNull())
820   {
821     // additional transformation matrix could be applied to
822     // render only those parts of viewport that will be
823     // passed to a printer as a current "frame" to provide
824     // tiling; scaling of graphics by matrix helps render a
825     // part of a view (frame) in same viewport, but with higher
826     // resolution
827
828     // set printing scale/tiling transformation
829     aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation());
830     aContext->ApplyProjectionMatrix();
831
832     // printing operation also assumes other viewport dimension
833     // to comply with transformation matrix or graphics scaling
834     // factors for tiling for layer redraw
835     GLsizei anViewportX = 0;
836     GLsizei anViewportY = 0;
837     thePrintContext->GetLayerViewport (anViewportX, anViewportY);
838     if (anViewportX != 0 && anViewportY != 0)
839       aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY);
840   }
841 #endif
842
843   glOrtho (left, right, bottom, top, -1.0, 1.0);
844
845   glPushAttrib (
846     GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
847     GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
848
849   glDisable (GL_DEPTH_TEST);
850   glDisable (GL_TEXTURE_1D);
851   glDisable (GL_TEXTURE_2D);
852   glDisable (GL_LIGHTING);
853
854   // TODO: Obsolete code, the display list is always empty now, to be removed
855   glCallList (ACLayer.ptrLayer->listIndex);
856
857   //calling dynamic render of LayerItems
858   if ( ACLayer.ptrLayer->layerData )
859   {
860     InitLayerProp (ACLayer.ptrLayer->listIndex);
861     ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
862     InitLayerProp (0);
863   }
864
865   glPopAttrib ();
866
867   aContext->WorldViewState.Pop();
868   aContext->ProjectionState.Pop();
869
870   aContext->ApplyProjectionMatrix();
871   aContext->ApplyWorldViewMatrix();
872
873   if (!ACLayer.sizeDependent)
874     aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height());
875
876   glFlush ();
877 #endif
878 }
879
880 /*----------------------------------------------------------------------*/
881
882 void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
883 {
884   // display global trihedron
885   if (myToShowTrihedron)
886   {
887     myTrihedron.Render (theWorkspace);
888   }
889   if (myToShowGradTrihedron)
890   {
891     myGraduatedTrihedron.Render (theWorkspace);
892   }
893 }
894
895 /*----------------------------------------------------------------------*/
896
897 //call_togl_create_bg_texture
898 void OpenGl_View::CreateBackgroundTexture (const Standard_CString  theFilePath,
899                                            const Aspect_FillMethod theFillStyle)
900 {
901   // Prepare aspect for texture storage
902   Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
903   Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
904   aTextureMap->EnableRepeat();
905   aTextureMap->DisableModulate();
906   aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
907                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
908                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
909   anAspect->SetTextureMap (aTextureMap);
910   anAspect->SetInteriorStyle (Aspect_IS_SOLID);
911   // Enable texture mapping
912   if (aTextureMap->IsDone())
913   {
914     anAspect->SetTextureMapOn();
915   }
916   else
917   {
918     anAspect->SetTextureMapOff();
919     return;
920
921   }
922
923   // Set texture parameters
924   myTextureParams->SetAspect (anAspect);
925
926   myBgTextureArray->SetTextureParameters (theFillStyle);
927 }
928
929 /*----------------------------------------------------------------------*/
930
931 //call_togl_set_bg_texture_style
932 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod theFillStyle)
933 {
934   myBgTextureArray->SetTextureFillMethod (theFillStyle);
935 }
936
937 /*----------------------------------------------------------------------*/
938
939 //call_togl_gradient_background
940 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& theColor1,
941                                         const Quantity_Color& theColor2,
942                                         const Aspect_GradientFillMethod theType)
943 {
944   myBgGradientArray->SetGradientParameters (theColor1, theColor2, theType);
945 }
946
947 /*----------------------------------------------------------------------*/
948
949 //call_togl_set_gradient_type
950 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod theType)
951 {
952   myBgGradientArray->SetGradientFillMethod (theType);
953 }
954
955 //=======================================================================
956 //function : AddZLayer
957 //purpose  :
958 //=======================================================================
959
960 void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
961 {
962   myZLayers.AddLayer (theLayerId);
963 }
964
965 //=======================================================================
966 //function : RemoveZLayer
967 //purpose  :
968 //=======================================================================
969
970 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
971 {
972   myZLayers.RemoveLayer (theLayerId);
973 }
974
975 //=======================================================================
976 //function : DisplayStructure
977 //purpose  :
978 //=======================================================================
979
980 void OpenGl_View::DisplayStructure (const Handle(Graphic3d_Structure)& theStructure,
981                                     const Standard_Integer             thePriority)
982 {
983   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
984   const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
985   myZLayers.AddStructure (aStruct, aZLayer, thePriority);
986 }
987
988 //=======================================================================
989 //function : DisplayImmediateStructure
990 //purpose  :
991 //=======================================================================
992
993 void OpenGl_View::DisplayImmediateStructure (const Handle(Graphic3d_Structure)& theStructure)
994 {
995   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
996   for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
997        anIter.More(); anIter.Next())
998   {
999     if (anIter.Value() == aStruct)
1000     {
1001       return;
1002     }
1003   }
1004
1005   myImmediateList.Append (aStruct);
1006 }
1007
1008 //=======================================================================
1009 //function : EraseStructure
1010 //purpose  :
1011 //=======================================================================
1012
1013 void OpenGl_View::EraseStructure (const Handle(Graphic3d_Structure)& theStructure)
1014 {
1015   myZLayers.RemoveStructure (theStructure);
1016 }
1017
1018 //=======================================================================
1019 //function : EraseImmediateStructure
1020 //purpose  :
1021 //=======================================================================
1022
1023 void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
1024 {
1025   for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1026        anIter.More(); anIter.Next())
1027   {
1028     if (anIter.Value() == theStructure)
1029     {
1030       myImmediateList.Remove (anIter);
1031       return;
1032     }
1033   }
1034 }
1035
1036 //=======================================================================
1037 //function : ChangeZLayer
1038 //purpose  :
1039 //=======================================================================
1040
1041 void OpenGl_View::ChangeZLayer (const OpenGl_Structure*  theStructure,
1042                                 const Graphic3d_ZLayerId theNewLayerId)
1043 {
1044   const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
1045   myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
1046 }
1047
1048 //=======================================================================
1049 //function : SetZLayerSettings
1050 //purpose  :
1051 //=======================================================================
1052 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
1053                                      const Graphic3d_ZLayerSettings& theSettings)
1054 {
1055   myZLayers.SetLayerSettings (theLayerId, theSettings);
1056 }
1057
1058 //=======================================================================
1059 //function : ChangePriority
1060 //purpose  :
1061 //=======================================================================
1062 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
1063                                   const Standard_Integer theNewPriority)
1064 {
1065   const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
1066   myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
1067 }
1068
1069 //=======================================================================
1070 //function : RedrawScene
1071 //purpose  :
1072 //=======================================================================
1073
1074 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
1075                                const Handle(OpenGl_Workspace)&      theWorkspace,
1076                                const Graphic3d_CView&               theCView,
1077                                const Standard_Boolean               theToDrawImmediate)
1078 {
1079   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
1080
1081   if (myZClip.Back.IsOn || myZClip.Front.IsOn)
1082   {
1083     Handle(Graphic3d_ClipPlane) aPlaneBack;
1084     Handle(Graphic3d_ClipPlane) aPlaneFront;
1085
1086     if (myZClip.Back.IsOn)
1087     {
1088       Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1089       if (myCamera->ZFar() < aClipBackConverted)
1090       {
1091         aClipBackConverted = myCamera->ZFar();
1092         myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1093       }
1094       const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1095       aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1096     }
1097
1098     if (myZClip.Front.IsOn)
1099     {
1100       Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1101       if (myCamera->ZNear() > aClipFrontConverted)
1102       {
1103         aClipFrontConverted = myCamera->ZNear();
1104         myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1105       }
1106       const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1107       aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1108     }
1109
1110     // Specify slicing planes with identity transformation
1111     if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1112     {
1113       Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1114       if (!aPlaneBack.IsNull())
1115       {
1116         aSlicingPlanes.Append (aPlaneBack);
1117       }
1118
1119       if (!aPlaneFront.IsNull())
1120       {
1121         aSlicingPlanes.Append (aPlaneFront);
1122       }
1123
1124       // add planes at loaded view matrix state
1125       aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1126     }
1127   }
1128
1129 #ifdef _WIN32
1130   // set printing scale/tiling transformation
1131   if (!thePrintContext.IsNull())
1132   {
1133     aContext->ProjectionState.Push();
1134     aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current());
1135     aContext->ApplyProjectionMatrix();
1136   }
1137 #endif
1138
1139   // Specify clipping planes in view transformation space
1140   if (!myClipPlanes.IsEmpty())
1141   {
1142     Graphic3d_SequenceOfHClipPlane aUserPlanes;
1143     Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1144     for (; aClippingIt.More(); aClippingIt.Next())
1145     {
1146       const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1147       if (aClipPlane->IsOn())
1148       {
1149         aUserPlanes.Append (aClipPlane);
1150       }
1151     }
1152
1153     if (!aUserPlanes.IsEmpty())
1154     {
1155       aContext->ChangeClipping().AddWorld (aUserPlanes);
1156     }
1157
1158     if (!aContext->ShaderManager()->IsEmpty())
1159     {
1160       aContext->ShaderManager()->UpdateClippingState();
1161     }
1162   }
1163
1164 #if !defined(GL_ES_VERSION_2_0)
1165   // Apply Lights
1166   if (aContext->core11 != NULL)
1167   {
1168     // setup lights
1169     Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1170                                    THE_DEFAULT_AMBIENT[1],
1171                                    THE_DEFAULT_AMBIENT[2],
1172                                    THE_DEFAULT_AMBIENT[3]);
1173     GLenum aLightGlId = GL_LIGHT0;
1174     for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1175          aLightIt.More(); aLightIt.Next())
1176     {
1177       bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace);
1178     }
1179
1180     // apply accumulated ambient color
1181     anAmbientColor.a() = 1.0f;
1182     glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1183
1184     if (aLightGlId != GL_LIGHT0)
1185     {
1186       glEnable (GL_LIGHTING);
1187     }
1188     // switch off unused lights
1189     for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1190     {
1191       glDisable (aLightGlId);
1192     }
1193   }
1194 #endif
1195
1196   // Clear status bitfields
1197   theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1198
1199   // Update state of surface detail level
1200   theWorkspace->GetGlContext()->ShaderManager()->UpdateSurfaceDetailStateTo (mySurfaceDetail);
1201
1202   // Added PCT for handling of textures
1203   switch (mySurfaceDetail)
1204   {
1205     case Visual3d_TOD_NONE:
1206       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1207       theWorkspace->DisableTexture();
1208       // Render the view
1209       RenderStructs (theWorkspace, theCView, theToDrawImmediate);
1210       break;
1211
1212     case Visual3d_TOD_ENVIRONMENT:
1213       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1214       theWorkspace->EnableTexture (myTextureEnv);
1215       // Render the view
1216       RenderStructs (theWorkspace, theCView, theToDrawImmediate);
1217       theWorkspace->DisableTexture();
1218       break;
1219
1220     case Visual3d_TOD_ALL:
1221       // First pass
1222       theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1223       // Render the view
1224       RenderStructs (theWorkspace, theCView, theToDrawImmediate);
1225       theWorkspace->DisableTexture();
1226
1227       // Second pass
1228       if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1229       {
1230         theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1231         theWorkspace->EnableTexture (myTextureEnv);
1232
1233         // Remember OpenGl properties
1234         GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
1235         GLint aSaveZbuffFunc;
1236         GLboolean aSaveZbuffWrite;
1237         glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1238         glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1239       #if !defined(GL_ES_VERSION_2_0)
1240         glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1241         glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1242       #endif
1243         GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1244         GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1245
1246         // Change the properties for second rendering pass
1247         glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1248         glEnable (GL_BLEND);
1249
1250         glDepthFunc (GL_EQUAL);
1251         glDepthMask (GL_FALSE);
1252         glEnable (GL_DEPTH_TEST);
1253
1254         theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1255
1256         // Render the view
1257         RenderStructs (theWorkspace, theCView, theToDrawImmediate);
1258         theWorkspace->DisableTexture();
1259
1260         // Restore properties back
1261         glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1262         if (!wasBlendEnabled)
1263           glDisable (GL_BLEND);
1264
1265         glDepthFunc (aSaveZbuffFunc);
1266         glDepthMask (aSaveZbuffWrite);
1267         if (!wasZbuffEnabled)
1268           glDisable (GL_DEPTH_FUNC);
1269       }
1270       break;
1271   }
1272
1273   // Apply restored view matrix.
1274   aContext->ApplyWorldViewMatrix();
1275
1276 #ifdef _WIN32
1277   // set printing scale/tiling transformation
1278   if (!thePrintContext.IsNull())
1279   {
1280     aContext->ProjectionState.Pop();
1281     aContext->ApplyProjectionMatrix();
1282   }
1283 #endif
1284
1285 }