0025219: Visualization, TKOpenGl - disable code paths unavailable on OpenGL ES 2.0
[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   Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
371
372   OPENGL_CLIP_PLANE *aOldPlanes = new OPENGL_CLIP_PLANE[aMaxPlanes];
373   OPENGL_CLIP_PLANE *aPtrPlane = aOldPlanes;
374
375   GLenum aClipPlaneId = GL_CLIP_PLANE0;
376   const GLenum aClipLastId = GL_CLIP_PLANE0 + aMaxPlanes;
377   for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
378   {
379     glGetClipPlane (aClipPlaneId, aPtrPlane->Equation);
380     if (aPtrPlane->isEnabled)
381     {
382       glDisable (aClipPlaneId);
383       aPtrPlane->isEnabled = GL_TRUE;
384     }
385     else
386     {
387       aPtrPlane->isEnabled = GL_FALSE;
388     }
389   }
390 #endif
391
392   Standard_Boolean isProjectionMatUpdateNeeded  = Standard_False;
393   Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
394   if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
395   {
396     isProjectionMatUpdateNeeded = Standard_True;
397     myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState();
398   }
399   if (myBVHSelector.ModelViewState() != myCamera->ModelViewState())
400   {
401     isOrientationMatUpdateNeeded = Standard_True;
402     myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
403   }
404
405   // Set OCCT state uniform variables
406   const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
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     {
417       myProjectionState = myCamera->ProjectionState();
418       aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
419     }
420
421     if (myModelViewState != myCamera->ModelViewState())
422     {
423       myModelViewState = myCamera->ModelViewState();
424       aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
425     }
426
427     if (aManager->ModelWorldState().Index() == 0)
428     {
429       Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
430                                     { 0.f, 1.f, 0.f, 0.f },
431                                     { 0.f, 0.f, 1.f, 0.f },
432                                     { 0.f, 0.f, 0.f, 1.f } };
433
434       aContext->ShaderManager()->UpdateModelWorldStateTo (&aModelWorldState);
435     }
436   }
437
438   if (!aManager.IsNull())
439   {
440     if (!aManager->IsSameView (this))
441     {
442       // Force update camera states
443       myProjectionState = myCamera->ProjectionState();
444       aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
445
446       myModelViewState = myCamera->ModelViewState();
447       aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
448     }
449   }
450
451   if (isProjectionMatUpdateNeeded
452    || isOrientationMatUpdateNeeded)
453   {
454     myBVHSelector.SetViewVolume (myCamera);
455   }
456
457   // ====================================
458   //      Step 2: Redraw background
459   // ====================================
460
461   // Render background
462   if (theWorkspace->ToRedrawGL())
463   {
464     DrawBackground (*theWorkspace);
465   }
466
467 #if !defined(GL_ES_VERSION_2_0)
468   // Switch off lighting by default
469   glDisable(GL_LIGHTING);
470 #endif
471
472   // =================================
473   //      Step 3: Draw underlayer
474   // =================================
475
476   RedrawLayer2d (thePrintContext, theCView, theCUnderLayer);
477
478   // =================================
479   //      Step 4: Redraw main plane
480   // =================================
481
482   // Setup face culling
483   GLboolean isCullFace = GL_FALSE;
484   if ( myBackfacing )
485   {
486     isCullFace = glIsEnabled( GL_CULL_FACE );
487     if ( myBackfacing < 0 )
488     {
489       glEnable( GL_CULL_FACE );
490       glCullFace( GL_BACK );
491     }
492     else
493       glDisable( GL_CULL_FACE );
494   }
495
496 #if !defined(GL_ES_VERSION_2_0)
497   // if the view is scaled normal vectors are scaled to unit
498   // length for correct displaying of shaded objects
499   const gp_Pnt anAxialScale = myCamera->AxialScale();
500   if(anAxialScale.X() != 1.F ||
501      anAxialScale.Y() != 1.F ||
502      anAxialScale.Z() != 1.F)
503     glEnable(GL_NORMALIZE);
504   else if(glIsEnabled(GL_NORMALIZE))
505     glDisable(GL_NORMALIZE);
506
507   // Apply Fog
508   if ( myFog.IsOn )
509   {
510     Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
511     if (myCamera->ZFar() < aFogFrontConverted)
512     {
513       aFogFrontConverted = myCamera->ZFar();
514       myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
515     }
516
517     Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
518     if (myCamera->ZFar() < aFogFrontConverted)
519     {
520       aFogBackConverted = myCamera->ZFar();
521       myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
522     }
523
524     if (aFogFrontConverted > aFogBackConverted)
525     {
526       myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
527       myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
528     }
529
530     glFogi(GL_FOG_MODE, GL_LINEAR);
531     glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
532     glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
533     glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
534     glEnable(GL_FOG);
535   }
536   else
537     glDisable(GL_FOG);
538
539   // Apply InteriorShadingMethod
540   glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
541 #endif
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     const OpenGl_Matrix* aProj = (const OpenGl_Matrix*) &myCamera->ProjectionMatrixF();
559
560     const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
561
562     // redraw scene with normal orientation and projection
563     RedrawScene (thePrintContext, theWorkspace, aProj, aOrient);
564   }
565   else
566   {
567     // two stereographic passes
568     const OpenGl_Matrix* aLProj  = (const OpenGl_Matrix*) &myCamera->ProjectionStereoLeftF();
569     const OpenGl_Matrix* aRProj  = (const OpenGl_Matrix*) &myCamera->ProjectionStereoRightF();
570     const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
571
572     // safely switch to left Eye buffer
573     aContext->SetDrawBufferLeft();
574
575     // redraw left Eye
576     RedrawScene (thePrintContext, theWorkspace, aLProj, aOrient);
577
578     // reset depth buffer of first rendering pass
579     if (theWorkspace->UseDepthTest())
580     {
581       glClear (GL_DEPTH_BUFFER_BIT);
582     }
583     // safely switch to right Eye buffer
584     aContext->SetDrawBufferRight();
585
586     // redraw right Eye
587     RedrawScene (thePrintContext, theWorkspace, aRProj, aOrient);
588
589     // switch back to monographic rendering
590     aContext->SetDrawBufferMono();
591   }
592
593   // ===============================
594   //      Step 5: Trihedron
595   // ===============================
596
597   // Resetting GL parameters according to the default aspects
598   // in order to synchronize GL state with the graphic driver state
599   // before drawing auxiliary stuff (trihedrons, overlayer)
600   // and invoking optional callbacks
601   theWorkspace->ResetAppliedAspect();
602
603   aContext->ChangeClipping().RemoveAll();
604
605   if (!aManager->IsEmpty())
606   {
607     aManager->ResetMaterialStates();
608     aManager->RevertClippingState();
609
610     // We need to disable (unbind) all shaders programs to ensure
611     // that all objects without specified aspect will be drawn
612     // correctly (such as background)
613     aContext->BindProgram (NULL);
614   }
615
616   // Render trihedron
617   if (theWorkspace->ToRedrawGL())
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
638   const int aMode = 0;
639   theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
640
641   RedrawLayer2d (thePrintContext, theCView, theCOverLayer);
642
643   theWorkspace->DisplayCallback (theCView, aMode);
644
645   // ===============================
646   //      Step 7: Finalize
647   // ===============================
648
649   // Restore clipping planes
650 #if !defined(GL_ES_VERSION_2_0)
651   aClipPlaneId = GL_CLIP_PLANE0;
652   aPtrPlane = aOldPlanes;
653
654   for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
655   {
656     glClipPlane (aClipPlaneId, aPtrPlane->Equation);
657     if (aPtrPlane->isEnabled)
658       glEnable (aClipPlaneId);
659     else
660       glDisable (aClipPlaneId);
661   }
662
663   delete[] aOldPlanes;
664 #endif
665
666   // ==============================================================
667   //      Step 8: Keep shader manager informed about last View
668   // ==============================================================
669
670   if (!aManager.IsNull())
671   {
672     aManager->SetLastView (this);
673   }
674 }
675
676 // =======================================================================
677 // function : InvalidateBVHData
678 // purpose  :
679 // =======================================================================
680 void OpenGl_View::InvalidateBVHData (const Standard_Integer theLayerId)
681 {
682   myZLayers.InvalidateBVHData (theLayerId);
683 }
684
685 /*----------------------------------------------------------------------*/
686
687 //ExecuteViewDisplay
688 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
689 {
690   if ( myZLayers.NbStructures() <= 0 )
691     return;
692
693 #if !defined(GL_ES_VERSION_2_0)
694   glPushAttrib ( GL_DEPTH_BUFFER_BIT );
695 #endif
696
697   //TsmPushAttri(); /* save previous graphics context */
698
699   if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
700   {
701   #if !defined(GL_ES_VERSION_2_0)
702     const int antiAliasingMode = AWorkspace->AntiAliasingMode();
703   #endif
704
705     if ( !myAntiAliasing )
706     {
707     #if !defined(GL_ES_VERSION_2_0)
708       glDisable(GL_POINT_SMOOTH);
709       glDisable(GL_LINE_SMOOTH);
710       if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
711     #endif
712       glBlendFunc (GL_ONE, GL_ZERO);
713       glDisable (GL_BLEND);
714     }
715     else
716     {
717     #if !defined(GL_ES_VERSION_2_0)
718       glEnable(GL_POINT_SMOOTH);
719       glEnable(GL_LINE_SMOOTH);
720       if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
721     #endif
722       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
723       glEnable (GL_BLEND);
724     }
725   }
726
727   myZLayers.Render (AWorkspace);
728
729 #if !defined(GL_ES_VERSION_2_0)
730   //TsmPopAttri(); /* restore previous graphics context; before update lights */
731   glPopAttrib();
732 #endif
733 }
734
735 /*----------------------------------------------------------------------*/
736
737 //call_togl_redraw_layer2d
738 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
739                                  const Graphic3d_CView&               ACView,
740                                  const Aspect_CLayer2d&               ACLayer)
741 {
742 #if !defined(GL_ES_VERSION_2_0)
743   if (&ACLayer == NULL
744    || ACLayer.ptrLayer == NULL
745    || ACLayer.ptrLayer->listIndex == 0) return;
746
747   GLsizei dispWidth  = (GLsizei )ACLayer.viewport[0];
748   GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
749
750   glMatrixMode( GL_MODELVIEW );
751   glPushMatrix ();
752   glLoadIdentity ();
753
754   glMatrixMode (GL_PROJECTION);
755   glPushMatrix ();
756   glLoadIdentity ();
757
758   if (!ACLayer.sizeDependent)
759     glViewport (0, 0, dispWidth, dispHeight);
760
761   float left = ACLayer.ortho[0];
762   float right = ACLayer.ortho[1];
763   float bottom = ACLayer.ortho[2];
764   float top = ACLayer.ortho[3];
765
766   int attach = ACLayer.attach;
767
768   float ratio;
769   if (!ACLayer.sizeDependent)
770     ratio = (float) dispWidth/dispHeight;
771   else
772     ratio = ACView.DefWindow.dx/ACView.DefWindow.dy;
773
774   float delta;
775   if (ratio >= 1.0) {
776     delta = (float )((top - bottom)/2.0);
777     switch (attach) {
778       case 0: /* Aspect_TOC_BOTTOM_LEFT */
779         top = bottom + 2*delta/ratio;
780         break;
781       case 1: /* Aspect_TOC_BOTTOM_RIGHT */
782         top = bottom + 2*delta/ratio;
783         break;
784       case 2: /* Aspect_TOC_TOP_LEFT */
785         bottom = top - 2*delta/ratio;
786         break;
787       case 3: /* Aspect_TOC_TOP_RIGHT */
788         bottom = top - 2*delta/ratio;
789         break;
790     }
791   }
792   else {
793     delta = (float )((right - left)/2.0);
794     switch (attach) {
795       case 0: /* Aspect_TOC_BOTTOM_LEFT */
796         right = left + 2*delta*ratio;
797         break;
798       case 1: /* Aspect_TOC_BOTTOM_RIGHT */
799         left = right - 2*delta*ratio;
800         break;
801       case 2: /* Aspect_TOC_TOP_LEFT */
802         right = left + 2*delta*ratio;
803         break;
804       case 3: /* Aspect_TOC_TOP_RIGHT */
805         left = right - 2*delta*ratio;
806         break;
807     }
808   }
809
810 #ifdef _WIN32
811   // Check printer context that exists only for print operation
812   if (!thePrintContext.IsNull())
813   {
814     // additional transformation matrix could be applied to
815     // render only those parts of viewport that will be
816     // passed to a printer as a current "frame" to provide
817     // tiling; scaling of graphics by matrix helps render a
818     // part of a view (frame) in same viewport, but with higher
819     // resolution
820     thePrintContext->LoadProjTransformation();
821
822     // printing operation also assumes other viewport dimension
823     // to comply with transformation matrix or graphics scaling
824     // factors for tiling for layer redraw
825     GLsizei anViewportX = 0;
826     GLsizei anViewportY = 0;
827     thePrintContext->GetLayerViewport (anViewportX, anViewportY);
828     if (anViewportX != 0 && anViewportY != 0)
829       glViewport (0, 0, anViewportX, anViewportY);
830   }
831 #endif
832
833   glOrtho (left, right, bottom, top, -1.0, 1.0);
834
835   glPushAttrib (
836     GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
837     GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
838
839   glDisable (GL_DEPTH_TEST);
840   glDisable (GL_TEXTURE_1D);
841   glDisable (GL_TEXTURE_2D);
842   glDisable (GL_LIGHTING);
843
844   // TODO: Obsolete code, the display list is always empty now, to be removed
845   glCallList (ACLayer.ptrLayer->listIndex);
846
847   //calling dynamic render of LayerItems
848   if ( ACLayer.ptrLayer->layerData )
849   {
850     InitLayerProp (ACLayer.ptrLayer->listIndex);
851     ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
852     InitLayerProp (0);
853   }
854
855   glPopAttrib ();
856
857   glMatrixMode (GL_PROJECTION);
858   glPopMatrix ();
859
860   glMatrixMode( GL_MODELVIEW );
861   glPopMatrix ();
862
863   if (!ACLayer.sizeDependent)
864     glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
865
866   glFlush ();
867 #endif
868 }
869
870 /*----------------------------------------------------------------------*/
871
872 void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
873 {
874   // display global trihedron
875   if (myTrihedron != NULL)
876   {
877     myTrihedron->Render (theWorkspace);
878   }
879   if (myGraduatedTrihedron != NULL)
880   {
881     myGraduatedTrihedron->Render (theWorkspace);
882   }
883 }
884
885 /*----------------------------------------------------------------------*/
886
887 //call_togl_create_bg_texture
888 void OpenGl_View::CreateBackgroundTexture (const Standard_CString  theFilePath,
889                                            const Aspect_FillMethod theFillStyle)
890 {
891   if (myBgTexture.TexId != 0)
892   {
893     // delete existing texture
894     glDeleteTextures (1, (GLuint* )&(myBgTexture.TexId));
895     myBgTexture.TexId = 0;
896   }
897
898   // load image from file
899   Image_AlienPixMap anImageLoaded;
900   if (!anImageLoaded.Load (theFilePath))
901   {
902     return;
903   }
904
905   Image_PixMap anImage;
906   if (anImageLoaded.RowExtraBytes() == 0 &&
907       (anImageLoaded.Format() == Image_PixMap::ImgRGB
908     || anImageLoaded.Format() == Image_PixMap::ImgRGB32
909     || anImageLoaded.Format() == Image_PixMap::ImgRGBA))
910   {
911     anImage.InitWrapper (anImageLoaded.Format(), anImageLoaded.ChangeData(),
912                          anImageLoaded.SizeX(), anImageLoaded.SizeY(), anImageLoaded.SizeRowBytes());
913   }
914   else
915   {
916     // convert image to RGB format
917     if (!anImage.InitTrash (Image_PixMap::ImgRGB, anImageLoaded.SizeX(), anImageLoaded.SizeY()))
918     {
919       return;
920     }
921
922     anImage.SetTopDown (false);
923     Quantity_Color aSrcColor;
924     for (Standard_Size aRow = 0; aRow < anImage.SizeY(); ++aRow)
925     {
926       for (Standard_Size aCol = 0; aCol < anImage.SizeX(); ++aCol)
927       {
928         aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
929         Image_ColorRGB& aColor = anImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
930         aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
931         aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
932         aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
933       }
934     }
935     anImageLoaded.Clear();
936   }
937
938   // create MipMapped texture
939   glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
940
941   GLuint aTextureId = 0;
942   glGenTextures (1, &aTextureId);
943   glBindTexture (GL_TEXTURE_2D, aTextureId);
944
945   glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_REPEAT);
946   glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_REPEAT);
947   glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
948   glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
949
950   const GLenum aDataFormat = (anImage.Format() == Image_PixMap::ImgRGB) ? GL_RGB : GL_RGBA;
951
952 #if !defined(GL_ES_VERSION_2_0)
953   gluBuild2DMipmaps (GL_TEXTURE_2D, 3/*4*/,
954                      GLint(anImage.SizeX()), GLint(anImage.SizeY()),
955                      aDataFormat, GL_UNSIGNED_BYTE, anImage.Data());
956 #endif
957
958   myBgTexture.TexId  = aTextureId;
959   myBgTexture.Width  = (Standard_Integer )anImage.SizeX();
960   myBgTexture.Height = (Standard_Integer )anImage.SizeY();
961   myBgTexture.Style  = theFillStyle;
962 }
963
964 /*----------------------------------------------------------------------*/
965
966 //call_togl_set_bg_texture_style
967 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
968 {
969   myBgTexture.Style = AFillStyle;
970 }
971
972 /*----------------------------------------------------------------------*/
973
974 //call_togl_gradient_background
975 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
976                                         const Quantity_Color& AColor2,
977                                         const Aspect_GradientFillMethod AType)
978 {
979   Standard_Real R,G,B;
980   AColor1.Values( R, G, B, Quantity_TOC_RGB );
981   myBgGradient.color1.rgb[0] = ( Tfloat )R;
982   myBgGradient.color1.rgb[1] = ( Tfloat )G;
983   myBgGradient.color1.rgb[2] = ( Tfloat )B;
984   myBgGradient.color1.rgb[3] = 0.F;
985
986   AColor2.Values( R, G, B, Quantity_TOC_RGB );
987   myBgGradient.color2.rgb[0] = ( Tfloat )R;
988   myBgGradient.color2.rgb[1] = ( Tfloat )G;
989   myBgGradient.color2.rgb[2] = ( Tfloat )B;
990   myBgGradient.color2.rgb[3] = 0.F;
991
992   myBgGradient.type = AType;
993 }
994
995 /*----------------------------------------------------------------------*/
996
997 //call_togl_set_gradient_type
998 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
999 {
1000   myBgGradient.type = AType;
1001 }
1002
1003 //=======================================================================
1004 //function : AddZLayer
1005 //purpose  :
1006 //=======================================================================
1007
1008 void OpenGl_View::AddZLayer (const Standard_Integer theLayerId)
1009 {
1010   myZLayers.AddLayer (theLayerId);
1011 }
1012
1013 //=======================================================================
1014 //function : RemoveZLayer
1015 //purpose  :
1016 //=======================================================================
1017
1018 void OpenGl_View::RemoveZLayer (const Standard_Integer theLayerId)
1019 {
1020   myZLayers.RemoveLayer (theLayerId);
1021 }
1022
1023 //=======================================================================
1024 //function : DisplayStructure
1025 //purpose  :
1026 //=======================================================================
1027
1028 void OpenGl_View::DisplayStructure (const OpenGl_Structure *theStructure,
1029                                     const Standard_Integer  thePriority)
1030 {
1031   Standard_Integer aZLayer = theStructure->GetZLayer ();
1032   myZLayers.AddStructure (theStructure, aZLayer, thePriority);
1033 }
1034
1035 //=======================================================================
1036 //function : DisplayImmediateStructure
1037 //purpose  :
1038 //=======================================================================
1039
1040 void OpenGl_View::DisplayImmediateStructure (const OpenGl_Structure* theStructure)
1041 {
1042   for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1043        anIter.More(); anIter.Next())
1044   {
1045     if (anIter.Value() == theStructure)
1046     {
1047       return;
1048     }
1049   }
1050
1051   myImmediateList.Append (theStructure);
1052 }
1053
1054 //=======================================================================
1055 //function : EraseStructure
1056 //purpose  :
1057 //=======================================================================
1058
1059 void OpenGl_View::EraseStructure (const OpenGl_Structure *theStructure)
1060 {
1061   Standard_Integer aZLayer = theStructure->GetZLayer ();
1062   myZLayers.RemoveStructure (theStructure, aZLayer);
1063 }
1064
1065 //=======================================================================
1066 //function : EraseImmediateStructure
1067 //purpose  :
1068 //=======================================================================
1069
1070 void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
1071 {
1072   for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1073        anIter.More(); anIter.Next())
1074   {
1075     if (anIter.Value() == theStructure)
1076     {
1077       myImmediateList.Remove (anIter);
1078       return;
1079     }
1080   }
1081 }
1082
1083 //=======================================================================
1084 //function : ChangeZLayer
1085 //purpose  :
1086 //=======================================================================
1087
1088 void OpenGl_View::ChangeZLayer (const OpenGl_Structure *theStructure,
1089                                 const Standard_Integer  theNewLayerId)
1090 {
1091   Standard_Integer anOldLayer = theStructure->GetZLayer ();
1092   myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
1093 }
1094
1095 //=======================================================================
1096 //function : SetZLayerSettings
1097 //purpose  :
1098 //=======================================================================
1099 void OpenGl_View::SetZLayerSettings (const Standard_Integer theLayerId,
1100                                      const Graphic3d_ZLayerSettings theSettings)
1101 {
1102   myZLayers.Layer (theLayerId).SetLayerSettings (theSettings);
1103 }
1104
1105 //=======================================================================
1106 //function : ChangePriority
1107 //purpose  :
1108 //=======================================================================
1109 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
1110                                   const Standard_Integer theNewPriority)
1111 {
1112   Standard_Integer aLayerId = theStructure->GetZLayer();
1113   myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
1114 }
1115
1116 //=======================================================================
1117 //function : RedrawScene
1118 //purpose  :
1119 //=======================================================================
1120
1121 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
1122                                const Handle(OpenGl_Workspace)& theWorkspace,
1123                                const OpenGl_Matrix* theProjection,
1124                                const OpenGl_Matrix* theOrientation)
1125 {
1126   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
1127
1128   if (myZClip.Back.IsOn || myZClip.Front.IsOn)
1129   {
1130     Handle(Graphic3d_ClipPlane) aPlaneBack;
1131     Handle(Graphic3d_ClipPlane) aPlaneFront;
1132
1133     if (myZClip.Back.IsOn)
1134     {
1135       Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1136       if (myCamera->ZFar() < aClipBackConverted)
1137       {
1138         aClipBackConverted = myCamera->ZFar();
1139         myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1140       }
1141       const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1142       aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1143     }
1144
1145     if (myZClip.Front.IsOn)
1146     {
1147       Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1148       if (myCamera->ZNear() > aClipFrontConverted)
1149       {
1150         aClipFrontConverted = myCamera->ZNear();
1151         myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1152       }
1153       const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1154       aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1155     }
1156
1157     // do some "memory allocation"-wise optimization
1158     if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1159     {
1160       Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1161       if (!aPlaneBack.IsNull())
1162       {
1163         aSlicingPlanes.Append (aPlaneBack);
1164       }
1165
1166       if (!aPlaneFront.IsNull())
1167       {
1168         aSlicingPlanes.Append (aPlaneFront);
1169       }
1170
1171       // add planes at loaded view matrix state
1172       aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1173     }
1174   }
1175
1176   // Apply user clipping planes
1177   if (!myClipPlanes.IsEmpty())
1178   {
1179     Graphic3d_SequenceOfHClipPlane aUserPlanes;
1180     Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1181     for (; aClippingIt.More(); aClippingIt.Next())
1182     {
1183       const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1184       if (aClipPlane->IsOn())
1185       {
1186         aUserPlanes.Append (aClipPlane);
1187       }
1188     }
1189
1190     if (!aUserPlanes.IsEmpty())
1191     {
1192       // add planes at actual matrix state.
1193       aContext->ChangeClipping().AddWorld (aUserPlanes);
1194     }
1195
1196     if (!aContext->ShaderManager()->IsEmpty())
1197     {
1198       aContext->ShaderManager()->UpdateClippingState();
1199     }
1200   }
1201
1202 #if !defined(GL_ES_VERSION_2_0)
1203   // Setup view projection
1204   glMatrixMode (GL_PROJECTION);
1205
1206 #ifdef _WIN32
1207   // add printing scale/tiling transformation
1208   if (!thePrintContext.IsNull())
1209   {
1210     thePrintContext->LoadProjTransformation();
1211   }
1212   else
1213 #endif
1214     glLoadIdentity();
1215
1216   glMultMatrixf ((const GLfloat*)theProjection);
1217
1218   if (!thePrintContext.IsNull())
1219   {
1220     // update shader uniform projection matrix with new data
1221     Tmatrix3 aResultProjection;
1222     glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
1223     aContext->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
1224
1225     // force shader uniform restore on next frame
1226     myProjectionState = 0;
1227   }
1228 #endif
1229
1230   // Setup view orientation
1231   theWorkspace->SetViewMatrix (theOrientation);
1232
1233 #if !defined(GL_ES_VERSION_2_0)
1234   // Apply Lights
1235   {
1236     // setup lights
1237     Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1238                                    THE_DEFAULT_AMBIENT[1],
1239                                    THE_DEFAULT_AMBIENT[2],
1240                                    THE_DEFAULT_AMBIENT[3]);
1241     GLenum aLightGlId = GL_LIGHT0;
1242     for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1243          aLightIt.More(); aLightIt.Next())
1244     {
1245       bind_light (aLightIt.Value(), aLightGlId, anAmbientColor);
1246     }
1247
1248     // apply accumulated ambient color
1249     anAmbientColor.a() = 1.0f;
1250     glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1251
1252     if (aLightGlId != GL_LIGHT0)
1253     {
1254       glEnable (GL_LIGHTING);
1255     }
1256     // switch off unused lights
1257     for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1258     {
1259       glDisable (aLightGlId);
1260     }
1261   }
1262 #endif
1263
1264   // Clear status bitfields
1265   theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1266
1267   // Added PCT for handling of textures
1268   switch (mySurfaceDetail)
1269   {
1270     case Visual3d_TOD_NONE:
1271       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1272       theWorkspace->DisableTexture();
1273       // Render the view
1274       RenderStructs (theWorkspace);
1275       break;
1276
1277     case Visual3d_TOD_ENVIRONMENT:
1278       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1279       theWorkspace->EnableTexture (myTextureEnv);
1280       // Render the view
1281       RenderStructs (theWorkspace);
1282       theWorkspace->DisableTexture();
1283       break;
1284
1285     case Visual3d_TOD_ALL:
1286       // First pass
1287       theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1288       // Render the view
1289       RenderStructs (theWorkspace);
1290       theWorkspace->DisableTexture();
1291
1292       // Second pass
1293       if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1294       {
1295         theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1296         theWorkspace->EnableTexture (myTextureEnv);
1297
1298         // Remember OpenGl properties
1299         GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
1300         GLint aSaveZbuffFunc;
1301         GLboolean aSaveZbuffWrite;
1302         glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1303         glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1304       #if !defined(GL_ES_VERSION_2_0)
1305         glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1306         glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1307       #endif
1308         GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1309         GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1310
1311         // Change the properties for second rendering pass
1312         glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1313         glEnable (GL_BLEND);
1314
1315         glDepthFunc (GL_EQUAL);
1316         glDepthMask (GL_FALSE);
1317         glEnable (GL_DEPTH_TEST);
1318
1319         theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1320
1321         // Render the view
1322         RenderStructs (theWorkspace);
1323         theWorkspace->DisableTexture();
1324
1325         // Restore properties back
1326         glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1327         if (!wasBlendEnabled)
1328           glDisable (GL_BLEND);
1329
1330         glDepthFunc (aSaveZbuffFunc);
1331         glDepthMask (aSaveZbuffWrite);
1332         if (!wasZbuffEnabled)
1333           glDisable (GL_DEPTH_FUNC);
1334       }
1335       break;
1336   }
1337 }