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