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