9cad122f50dcb9e1fe3f9c9ffea634592e2f2052
[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())
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)& AWorkspace,
590                                  const Standard_Boolean          theToDrawImmediate)
591 {
592   if ( myZLayers.NbStructures() <= 0 )
593     return;
594
595   const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
596 #if !defined(GL_ES_VERSION_2_0)
597   if (aCtx->core11 != NULL)
598   {
599     aCtx->core11->glPushAttrib (GL_DEPTH_BUFFER_BIT);
600   }
601 #endif
602
603   //TsmPushAttri(); /* save previous graphics context */
604
605   if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
606   {
607   #if !defined(GL_ES_VERSION_2_0)
608     const int antiAliasingMode = AWorkspace->AntiAliasingMode();
609   #endif
610
611     if ( !myAntiAliasing )
612     {
613     #if !defined(GL_ES_VERSION_2_0)
614       if (aCtx->core11 != NULL)
615       {
616         glDisable (GL_POINT_SMOOTH);
617       }
618       glDisable(GL_LINE_SMOOTH);
619       if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
620     #endif
621       glBlendFunc (GL_ONE, GL_ZERO);
622       glDisable (GL_BLEND);
623     }
624     else
625     {
626     #if !defined(GL_ES_VERSION_2_0)
627       if (aCtx->core11 != NULL)
628       {
629         glEnable(GL_POINT_SMOOTH);
630       }
631       glEnable(GL_LINE_SMOOTH);
632       if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
633     #endif
634       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
635       glEnable (GL_BLEND);
636     }
637   }
638
639   myZLayers.Render (AWorkspace, theToDrawImmediate);
640
641 #if !defined(GL_ES_VERSION_2_0)
642   if (aCtx->core11 != NULL)
643   {
644     aCtx->core11->glPopAttrib();
645   }
646 #endif
647 }
648
649 /*----------------------------------------------------------------------*/
650
651 //call_togl_redraw_layer2d
652 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
653                                  const Handle(OpenGl_Workspace)&      theWorkspace,
654                                  const Graphic3d_CView&               /*ACView*/,
655                                  const Aspect_CLayer2d&               ACLayer)
656 {
657 #if !defined(GL_ES_VERSION_2_0)
658   if (&ACLayer == NULL
659    || ACLayer.ptrLayer == NULL
660    || ACLayer.ptrLayer->listIndex == 0) return;
661
662   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
663   if (aContext->core11 == NULL)
664   {
665     return;
666   }
667
668   GLsizei dispWidth  = (GLsizei )ACLayer.viewport[0];
669   GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
670
671   aContext->WorldViewState.Push();
672   aContext->ProjectionState.Push();
673
674   aContext->WorldViewState.SetIdentity();
675   aContext->ProjectionState.SetIdentity();
676
677   aContext->ApplyWorldViewMatrix();
678   aContext->ApplyProjectionMatrix();
679
680   if (!ACLayer.sizeDependent)
681     aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight);
682
683   float left = ACLayer.ortho[0];
684   float right = ACLayer.ortho[1];
685   float bottom = ACLayer.ortho[2];
686   float top = ACLayer.ortho[3];
687
688   int attach = ACLayer.attach;
689
690   const float ratio = !ACLayer.sizeDependent
691                     ? float(dispWidth) / float(dispHeight)
692                     : float(theWorkspace->Width()) / float(theWorkspace->Height());
693
694   float delta;
695   if (ratio >= 1.0) {
696     delta = (float )((top - bottom)/2.0);
697     switch (attach) {
698       case 0: /* Aspect_TOC_BOTTOM_LEFT */
699         top = bottom + 2*delta/ratio;
700         break;
701       case 1: /* Aspect_TOC_BOTTOM_RIGHT */
702         top = bottom + 2*delta/ratio;
703         break;
704       case 2: /* Aspect_TOC_TOP_LEFT */
705         bottom = top - 2*delta/ratio;
706         break;
707       case 3: /* Aspect_TOC_TOP_RIGHT */
708         bottom = top - 2*delta/ratio;
709         break;
710     }
711   }
712   else {
713     delta = (float )((right - left)/2.0);
714     switch (attach) {
715       case 0: /* Aspect_TOC_BOTTOM_LEFT */
716         right = left + 2*delta*ratio;
717         break;
718       case 1: /* Aspect_TOC_BOTTOM_RIGHT */
719         left = right - 2*delta*ratio;
720         break;
721       case 2: /* Aspect_TOC_TOP_LEFT */
722         right = left + 2*delta*ratio;
723         break;
724       case 3: /* Aspect_TOC_TOP_RIGHT */
725         left = right - 2*delta*ratio;
726         break;
727     }
728   }
729
730 #ifdef _WIN32
731   // Check printer context that exists only for print operation
732   if (!thePrintContext.IsNull())
733   {
734     // additional transformation matrix could be applied to
735     // render only those parts of viewport that will be
736     // passed to a printer as a current "frame" to provide
737     // tiling; scaling of graphics by matrix helps render a
738     // part of a view (frame) in same viewport, but with higher
739     // resolution
740
741     // set printing scale/tiling transformation
742     aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation());
743     aContext->ApplyProjectionMatrix();
744
745     // printing operation also assumes other viewport dimension
746     // to comply with transformation matrix or graphics scaling
747     // factors for tiling for layer redraw
748     GLsizei anViewportX = 0;
749     GLsizei anViewportY = 0;
750     thePrintContext->GetLayerViewport (anViewportX, anViewportY);
751     if (anViewportX != 0 && anViewportY != 0)
752       aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY);
753   }
754 #endif
755
756   glOrtho (left, right, bottom, top, -1.0, 1.0);
757
758   glPushAttrib (
759     GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
760     GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
761
762   glDisable (GL_DEPTH_TEST);
763   glDisable (GL_TEXTURE_1D);
764   glDisable (GL_TEXTURE_2D);
765   glDisable (GL_LIGHTING);
766
767   // TODO: Obsolete code, the display list is always empty now, to be removed
768   glCallList (ACLayer.ptrLayer->listIndex);
769
770   //calling dynamic render of LayerItems
771   if ( ACLayer.ptrLayer->layerData )
772   {
773     InitLayerProp (ACLayer.ptrLayer->listIndex);
774     ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
775     InitLayerProp (0);
776   }
777
778   glPopAttrib ();
779
780   aContext->WorldViewState.Pop();
781   aContext->ProjectionState.Pop();
782
783   aContext->ApplyProjectionMatrix();
784   aContext->ApplyWorldViewMatrix();
785
786   if (!ACLayer.sizeDependent)
787     aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height());
788
789   glFlush ();
790 #endif
791 }
792
793 /*----------------------------------------------------------------------*/
794
795 void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
796 {
797   // display global trihedron
798   if (myTrihedron != NULL)
799   {
800     myTrihedron->Render (theWorkspace);
801   }
802   if (myGraduatedTrihedron != NULL)
803   {
804     myGraduatedTrihedron->Render (theWorkspace);
805   }
806 }
807
808 /*----------------------------------------------------------------------*/
809
810 //call_togl_create_bg_texture
811 void OpenGl_View::CreateBackgroundTexture (const Standard_CString  theFilePath,
812                                            const Aspect_FillMethod theFillStyle)
813 {
814   // Prepare aspect for texture storage
815   Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
816   Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
817   aTextureMap->EnableRepeat();
818   aTextureMap->DisableModulate();
819   aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
820                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
821                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
822   anAspect->SetTextureMap (aTextureMap);
823   anAspect->SetInteriorStyle (Aspect_IS_SOLID);
824   // Enable texture mapping
825   if (aTextureMap->IsDone())
826   {
827     anAspect->SetTextureMapOn();
828   }
829   else
830   {
831     anAspect->SetTextureMapOff();
832     return;
833
834   }
835
836   // Set texture parameters
837   myTextureParams->SetAspect (anAspect);
838
839   myBgTextureArray->SetTextureParameters (theFillStyle);
840 }
841
842 /*----------------------------------------------------------------------*/
843
844 //call_togl_set_bg_texture_style
845 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod theFillStyle)
846 {
847   myBgTextureArray->SetTextureFillMethod (theFillStyle);
848 }
849
850 /*----------------------------------------------------------------------*/
851
852 //call_togl_gradient_background
853 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& theColor1,
854                                         const Quantity_Color& theColor2,
855                                         const Aspect_GradientFillMethod theType)
856 {
857   myBgGradientArray->SetGradientParameters (theColor1, theColor2, theType);
858 }
859
860 /*----------------------------------------------------------------------*/
861
862 //call_togl_set_gradient_type
863 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod theType)
864 {
865   myBgGradientArray->SetGradientFillMethod (theType);
866 }
867
868 //=======================================================================
869 //function : AddZLayer
870 //purpose  :
871 //=======================================================================
872
873 void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
874 {
875   myZLayers.AddLayer (theLayerId);
876 }
877
878 //=======================================================================
879 //function : RemoveZLayer
880 //purpose  :
881 //=======================================================================
882
883 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
884 {
885   myZLayers.RemoveLayer (theLayerId);
886 }
887
888 //=======================================================================
889 //function : DisplayStructure
890 //purpose  :
891 //=======================================================================
892
893 void OpenGl_View::DisplayStructure (const Handle(Graphic3d_Structure)& theStructure,
894                                     const Standard_Integer             thePriority)
895 {
896   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
897   const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
898   myZLayers.AddStructure (aStruct, aZLayer, thePriority);
899 }
900
901 //=======================================================================
902 //function : DisplayImmediateStructure
903 //purpose  :
904 //=======================================================================
905
906 void OpenGl_View::DisplayImmediateStructure (const Handle(Graphic3d_Structure)& theStructure)
907 {
908   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
909   for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
910        anIter.More(); anIter.Next())
911   {
912     if (anIter.Value() == aStruct)
913     {
914       return;
915     }
916   }
917
918   myImmediateList.Append (aStruct);
919 }
920
921 //=======================================================================
922 //function : EraseStructure
923 //purpose  :
924 //=======================================================================
925
926 void OpenGl_View::EraseStructure (const Handle(Graphic3d_Structure)& theStructure)
927 {
928   myZLayers.RemoveStructure (theStructure);
929 }
930
931 //=======================================================================
932 //function : EraseImmediateStructure
933 //purpose  :
934 //=======================================================================
935
936 void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
937 {
938   for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
939        anIter.More(); anIter.Next())
940   {
941     if (anIter.Value() == theStructure)
942     {
943       myImmediateList.Remove (anIter);
944       return;
945     }
946   }
947 }
948
949 //=======================================================================
950 //function : ChangeZLayer
951 //purpose  :
952 //=======================================================================
953
954 void OpenGl_View::ChangeZLayer (const OpenGl_Structure*  theStructure,
955                                 const Graphic3d_ZLayerId theNewLayerId)
956 {
957   const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
958   myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
959 }
960
961 //=======================================================================
962 //function : SetZLayerSettings
963 //purpose  :
964 //=======================================================================
965 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
966                                      const Graphic3d_ZLayerSettings& theSettings)
967 {
968   myZLayers.SetLayerSettings (theLayerId, theSettings);
969 }
970
971 //=======================================================================
972 //function : ChangePriority
973 //purpose  :
974 //=======================================================================
975 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
976                                   const Standard_Integer theNewPriority)
977 {
978   const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
979   myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
980 }
981
982 //=======================================================================
983 //function : RedrawScene
984 //purpose  :
985 //=======================================================================
986
987 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
988                                const Handle(OpenGl_Workspace)&      theWorkspace,
989                                const Standard_Boolean               theToDrawImmediate)
990 {
991   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
992
993   if (myZClip.Back.IsOn || myZClip.Front.IsOn)
994   {
995     Handle(Graphic3d_ClipPlane) aPlaneBack;
996     Handle(Graphic3d_ClipPlane) aPlaneFront;
997
998     if (myZClip.Back.IsOn)
999     {
1000       Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1001       if (myCamera->ZFar() < aClipBackConverted)
1002       {
1003         aClipBackConverted = myCamera->ZFar();
1004         myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1005       }
1006       const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1007       aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1008     }
1009
1010     if (myZClip.Front.IsOn)
1011     {
1012       Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1013       if (myCamera->ZNear() > aClipFrontConverted)
1014       {
1015         aClipFrontConverted = myCamera->ZNear();
1016         myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1017       }
1018       const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1019       aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1020     }
1021
1022     // Specify slicing planes with identity transformation
1023     if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1024     {
1025       Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1026       if (!aPlaneBack.IsNull())
1027       {
1028         aSlicingPlanes.Append (aPlaneBack);
1029       }
1030
1031       if (!aPlaneFront.IsNull())
1032       {
1033         aSlicingPlanes.Append (aPlaneFront);
1034       }
1035
1036       // add planes at loaded view matrix state
1037       aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1038     }
1039   }
1040
1041 #ifdef _WIN32
1042   // set printing scale/tiling transformation
1043   if (!thePrintContext.IsNull())
1044   {
1045     aContext->ProjectionState.Push();
1046     aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current());
1047     aContext->ApplyProjectionMatrix();
1048   }
1049 #endif
1050
1051   // Specify clipping planes in view transformation space
1052   if (!myClipPlanes.IsEmpty())
1053   {
1054     Graphic3d_SequenceOfHClipPlane aUserPlanes;
1055     Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1056     for (; aClippingIt.More(); aClippingIt.Next())
1057     {
1058       const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1059       if (aClipPlane->IsOn())
1060       {
1061         aUserPlanes.Append (aClipPlane);
1062       }
1063     }
1064
1065     if (!aUserPlanes.IsEmpty())
1066     {
1067       aContext->ChangeClipping().AddWorld (aUserPlanes);
1068     }
1069
1070     if (!aContext->ShaderManager()->IsEmpty())
1071     {
1072       aContext->ShaderManager()->UpdateClippingState();
1073     }
1074   }
1075
1076 #if !defined(GL_ES_VERSION_2_0)
1077   // Apply Lights
1078   if (aContext->core11 != NULL)
1079   {
1080     // setup lights
1081     Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1082                                    THE_DEFAULT_AMBIENT[1],
1083                                    THE_DEFAULT_AMBIENT[2],
1084                                    THE_DEFAULT_AMBIENT[3]);
1085     GLenum aLightGlId = GL_LIGHT0;
1086     for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1087          aLightIt.More(); aLightIt.Next())
1088     {
1089       bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace);
1090     }
1091
1092     // apply accumulated ambient color
1093     anAmbientColor.a() = 1.0f;
1094     glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1095
1096     if (aLightGlId != GL_LIGHT0)
1097     {
1098       glEnable (GL_LIGHTING);
1099     }
1100     // switch off unused lights
1101     for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1102     {
1103       glDisable (aLightGlId);
1104     }
1105   }
1106 #endif
1107
1108   // Clear status bitfields
1109   theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1110
1111   // Added PCT for handling of textures
1112   switch (mySurfaceDetail)
1113   {
1114     case Visual3d_TOD_NONE:
1115       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1116       theWorkspace->DisableTexture();
1117       // Render the view
1118       RenderStructs (theWorkspace, theToDrawImmediate);
1119       break;
1120
1121     case Visual3d_TOD_ENVIRONMENT:
1122       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1123       theWorkspace->EnableTexture (myTextureEnv);
1124       // Render the view
1125       RenderStructs (theWorkspace, theToDrawImmediate);
1126       theWorkspace->DisableTexture();
1127       break;
1128
1129     case Visual3d_TOD_ALL:
1130       // First pass
1131       theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1132       // Render the view
1133       RenderStructs (theWorkspace, theToDrawImmediate);
1134       theWorkspace->DisableTexture();
1135
1136       // Second pass
1137       if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1138       {
1139         theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1140         theWorkspace->EnableTexture (myTextureEnv);
1141
1142         // Remember OpenGl properties
1143         GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
1144         GLint aSaveZbuffFunc;
1145         GLboolean aSaveZbuffWrite;
1146         glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1147         glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1148       #if !defined(GL_ES_VERSION_2_0)
1149         glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1150         glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1151       #endif
1152         GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1153         GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1154
1155         // Change the properties for second rendering pass
1156         glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1157         glEnable (GL_BLEND);
1158
1159         glDepthFunc (GL_EQUAL);
1160         glDepthMask (GL_FALSE);
1161         glEnable (GL_DEPTH_TEST);
1162
1163         theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1164
1165         // Render the view
1166         RenderStructs (theWorkspace, theToDrawImmediate);
1167         theWorkspace->DisableTexture();
1168
1169         // Restore properties back
1170         glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1171         if (!wasBlendEnabled)
1172           glDisable (GL_BLEND);
1173
1174         glDepthFunc (aSaveZbuffFunc);
1175         glDepthMask (aSaveZbuffWrite);
1176         if (!wasZbuffEnabled)
1177           glDisable (GL_DEPTH_FUNC);
1178       }
1179       break;
1180   }
1181
1182   // Apply restored view matrix.
1183   aContext->ApplyWorldViewMatrix();
1184
1185 #ifdef _WIN32
1186   // set printing scale/tiling transformation
1187   if (!thePrintContext.IsNull())
1188   {
1189     aContext->ProjectionState.Pop();
1190     aContext->ApplyProjectionMatrix();
1191   }
1192 #endif
1193
1194 }