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