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