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