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