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