84f522cf9339eb272f95b164a6d97f07b3553bbb
[occt.git] / src / OpenGl / OpenGl_GraphicDriver_7.cxx
1 // Created on: 2011-10-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #include <OpenGl_GraphicDriver.hxx>
22
23 #include <OpenGl_FrameBuffer.hxx>
24
25 #include <OpenGl_Structure.hxx>
26 #include <OpenGl_CView.hxx>
27 #include <OpenGl_Display.hxx>
28 #include <OpenGl_Text.hxx>
29
30 /*----------------------------------------------------------------------*/
31
32 void OpenGl_GraphicDriver::ActivateView (const Graphic3d_CView& ACView)
33 {
34   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
35   if (aCView)
36     aCView->WS->SetActiveView(aCView->View);
37 }
38
39 void OpenGl_GraphicDriver::AntiAliasing (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
40 {
41   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
42   if (aCView)
43     aCView->View->SetAntiAliasing(AFlag);
44 }
45
46 void OpenGl_GraphicDriver::Background (const Graphic3d_CView& ACView)
47 {
48   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
49   if (aCView)
50   {
51     aCView->WS->SetBackgroundColor(ACView.DefWindow.Background.r,ACView.DefWindow.Background.g,ACView.DefWindow.Background.b);
52   }
53 }
54
55 void OpenGl_GraphicDriver::GradientBackground (const Graphic3d_CView& ACView,
56                                               const Quantity_Color& AColor1,
57                                               const Quantity_Color& AColor2,
58                                               const Aspect_GradientFillMethod AType)
59 {
60   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
61   if (aCView)
62   {
63     aCView->View->SetBackgroundGradient(AColor1,AColor2,AType);
64   }
65 }
66
67 void OpenGl_GraphicDriver::Blink (const Graphic3d_CStructure &, const Standard_Boolean)
68 {
69   // Do nothing
70 }
71
72 void OpenGl_GraphicDriver::BoundaryBox (const Graphic3d_CStructure& theCStructure,
73                                         const Standard_Boolean      toCreate)
74 {
75   OpenGl_Structure* aStructure = (OpenGl_Structure* )theCStructure.ptrStructure;
76   if (aStructure == NULL)
77     return;
78
79   if (toCreate)
80     aStructure->SetHighlightBox (GetSharedContext(), theCStructure.BoundBox);
81   else
82     aStructure->ClearHighlightBox (GetSharedContext());
83 }
84
85 void OpenGl_GraphicDriver::HighlightColor (const Graphic3d_CStructure& theCStructure,
86                                            const Standard_ShortReal R,
87                                            const Standard_ShortReal G,
88                                            const Standard_ShortReal B,
89                                            const Standard_Boolean   toCreate)
90 {
91   OpenGl_Structure* aStructure = (OpenGl_Structure* )theCStructure.ptrStructure;
92   if (aStructure == NULL)
93     return;
94
95   if (toCreate)
96     aStructure->SetHighlightColor (GetSharedContext(), R, G, B);
97   else
98     aStructure->ClearHighlightColor (GetSharedContext());
99 }
100
101 void OpenGl_GraphicDriver::NameSetStructure (const Graphic3d_CStructure& ACStructure)
102 {
103   OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
104   if (astructure)
105   {
106     Standard_Integer aStatus = 0;
107     if (ACStructure.highlight) aStatus |= OPENGL_NS_HIGHLIGHT;
108     if (!ACStructure.visible) aStatus |= OPENGL_NS_HIDE;
109     astructure->SetNamedStatus( aStatus );
110   }
111 }
112
113 void OpenGl_GraphicDriver::ClipLimit (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
114 {
115   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
116   if (aCView)
117   {
118     aCView->View->SetClipLimit(ACView);
119     if (!AWait)
120     {
121       aCView->WS->Resize(ACView.DefWindow);
122     }
123   }
124 }
125
126 void OpenGl_GraphicDriver::DeactivateView (const Graphic3d_CView& ACView)
127 {
128   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
129   if (aCView)
130   {
131     const Handle(OpenGl_View) aDummyView;
132     aCView->WS->SetActiveView(aDummyView);
133   }
134 }
135
136 void OpenGl_GraphicDriver::DepthCueing (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
137 {
138   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
139   if (aCView)
140     aCView->View->SetFog(ACView, AFlag);
141 }
142
143 Standard_Boolean OpenGl_GraphicDriver::ProjectRaster (const Graphic3d_CView& ACView, const Standard_ShortReal AX, const Standard_ShortReal AY, const Standard_ShortReal AZ, Standard_Integer& AU, Standard_Integer& AV)
144 {
145   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
146   if (!aCView)
147     return Standard_False;
148
149   Standard_Integer aWidth = aCView->WS->Width();
150   Standard_Integer aHeight = aCView->WS->Height();
151   Standard_ShortReal xr, yr;
152   if (aCView->View->ProjectObjectToRaster(aWidth, aHeight, AX, AY, AZ, xr, yr))
153   {
154     AU = (Standard_Integer) xr;
155     AV = aHeight - (Standard_Integer) yr;
156     return Standard_True;
157   }
158
159   return Standard_False;
160 }
161
162 Standard_Boolean OpenGl_GraphicDriver::UnProjectRaster (const Graphic3d_CView& ACView, const Standard_Integer /*Axm*/, const Standard_Integer Aym, const Standard_Integer /*AXM*/, const Standard_Integer AYM, const Standard_Integer AU, const Standard_Integer AV, Standard_ShortReal& Ax, Standard_ShortReal& Ay, Standard_ShortReal& Az)
163 {
164   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
165   if (!aCView)
166     return Standard_False;
167
168   const Standard_Integer aWidth = aCView->WS->Width();
169   const Standard_Integer aHeight = aCView->WS->Height();
170
171   /*
172   Patched by P.Dolbey: the window pixel height decreased by one
173   in order for yr to remain within valid coordinate range [0; Ym -1]
174   where Ym means window pixel height.
175   */
176   return aCView->View->ProjectRasterToObject( aWidth, aHeight, AU, (AYM-1)-Aym-AV, Ax, Ay, Az );
177 }
178
179 Standard_Boolean OpenGl_GraphicDriver::UnProjectRasterWithRay (const Graphic3d_CView& ACView, const Standard_Integer /*Axm*/, const Standard_Integer Aym, const Standard_Integer /*AXM*/, const Standard_Integer AYM, const Standard_Integer AU, const Standard_Integer AV, Standard_ShortReal& Ax, Standard_ShortReal& Ay, Standard_ShortReal& Az, Standard_ShortReal& Dx, Standard_ShortReal& Dy, Standard_ShortReal& Dz)
180 {
181   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
182   if (!aCView)
183     return Standard_False;
184
185   const Standard_Integer aWidth = aCView->WS->Width();
186   const Standard_Integer aHeight = aCView->WS->Height();
187
188   return aCView->View->ProjectRasterToObjectWithRay( aWidth, aHeight, AU, AYM-Aym-AV, Ax, Ay, Az, Dx, Dy, Dz );
189 }
190
191 void OpenGl_GraphicDriver::RatioWindow (const Graphic3d_CView& theCView)
192 {
193   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
194   if (aCView != NULL)
195     aCView->WS->Resize (theCView.DefWindow);
196 }
197
198 void OpenGl_GraphicDriver::Redraw (const Graphic3d_CView& ACView, 
199                                    const Aspect_CLayer2d& ACUnderLayer, 
200                                    const Aspect_CLayer2d& ACOverLayer, 
201                                    const Standard_Integer /*x*/, 
202                                    const Standard_Integer /*y*/, 
203                                    const Standard_Integer /*width*/, 
204                                    const Standard_Integer /*height*/)
205 {
206   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
207   if (aCView)
208   {
209     /*if( width <= 0 || height <= 0  )
210       aCView->WS->Redraw(ACView, ACUnderLayer, ACOverLayer);
211     else
212       aCView->WS->RedrawArea(ACView, ACUnderLayer, ACOverLayer, x, y, width, height);*/
213     // Always do full redraw
214     aCView->WS->Redraw(ACView, ACUnderLayer, ACOverLayer);
215   }
216 }
217
218 Graphic3d_PtrFrameBuffer OpenGl_GraphicDriver::FBOCreate (const Graphic3d_CView& ACView, const Standard_Integer theWidth, const Standard_Integer theHeight)
219 {
220   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
221   if (aCView)
222     return aCView->WS->FBOCreate(theWidth, theHeight);
223   return (Graphic3d_PtrFrameBuffer)NULL;
224 }
225
226 Graphic3d_PtrFrameBuffer OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth, const Standard_Integer theHeight)
227 {
228   // activate OpenGL context
229   if (!Activate())
230     return NULL;
231
232   // create the FBO
233   OpenGl_FrameBuffer* aFrameBuffer = new OpenGl_FrameBuffer();
234   if (!aFrameBuffer->Init (GetGlContext(), theWidth, theHeight))
235   {
236     delete aFrameBuffer;
237     return NULL;
238   }
239   return (Graphic3d_PtrFrameBuffer )aFrameBuffer;
240 }
241
242 void OpenGl_GraphicDriver::FBORelease (const Graphic3d_CView& ACView, Graphic3d_PtrFrameBuffer& theFBOPtr)
243 {
244   if (theFBOPtr == NULL)
245     return;
246   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
247   if (aCView)
248   {
249     aCView->WS->FBORelease(theFBOPtr);
250     theFBOPtr = NULL;
251   }
252 }
253
254 void OpenGl_Workspace::FBORelease (Graphic3d_PtrFrameBuffer theFBOPtr)
255 {
256   // activate OpenGL context
257   if (!Activate())
258     return;
259
260   // release the object
261   OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer*)theFBOPtr;
262   aFrameBuffer->Release (GetGlContext());
263   delete aFrameBuffer;
264 }
265
266 void OpenGl_GraphicDriver::FBOGetDimensions (const Graphic3d_CView& ,
267                                              const Graphic3d_PtrFrameBuffer theFBOPtr,
268                                              Standard_Integer& theWidth,    Standard_Integer& theHeight,
269                                              Standard_Integer& theWidthMax, Standard_Integer& theHeightMax)
270 {
271   if (theFBOPtr == NULL)
272   {
273     return;
274   }
275   const OpenGl_FrameBuffer* aFrameBuffer = (const OpenGl_FrameBuffer* )theFBOPtr;
276   theWidth  = aFrameBuffer->GetVPSizeX(); // current viewport size
277   theHeight = aFrameBuffer->GetVPSizeY();
278   theWidthMax  = aFrameBuffer->GetSizeX(); // texture size
279   theHeightMax = aFrameBuffer->GetSizeY();
280 }
281
282 void OpenGl_GraphicDriver::FBOChangeViewport (const Graphic3d_CView& ,
283                                               Graphic3d_PtrFrameBuffer& theFBOPtr,
284                                               const Standard_Integer theWidth, const Standard_Integer theHeight)
285 {
286   if (theFBOPtr == NULL)
287   {
288     return;
289   }
290   OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theFBOPtr;
291   aFrameBuffer->ChangeViewport (theWidth, theHeight);
292 }
293
294 inline bool getDataFormat (const Image_PixMap& theData,
295                            GLenum&             thePixelFormat,
296                            GLenum&             theDataType)
297 {
298   thePixelFormat = GL_RGB;
299   theDataType    = GL_UNSIGNED_BYTE;
300   switch (theData.Format())
301   {
302     case Image_PixMap::ImgGray:
303       thePixelFormat = GL_DEPTH_COMPONENT;
304       theDataType    = GL_UNSIGNED_BYTE;
305       return true;
306     case Image_PixMap::ImgRGB:
307       thePixelFormat = GL_RGB;
308       theDataType    = GL_UNSIGNED_BYTE;
309       return true;
310     case Image_PixMap::ImgBGR:
311       thePixelFormat = GL_BGR;
312       theDataType    = GL_UNSIGNED_BYTE;
313       return true;
314     case Image_PixMap::ImgRGBA:
315     case Image_PixMap::ImgRGB32:
316       thePixelFormat = GL_RGBA;
317       theDataType    = GL_UNSIGNED_BYTE;
318       return true;
319     case Image_PixMap::ImgBGRA:
320     case Image_PixMap::ImgBGR32:
321       thePixelFormat = GL_BGRA;
322       theDataType    = GL_UNSIGNED_BYTE;
323       return true;
324     case Image_PixMap::ImgGrayF:
325       thePixelFormat = GL_DEPTH_COMPONENT;
326       theDataType    = GL_FLOAT;
327       return true;
328     case Image_PixMap::ImgRGBF:
329       thePixelFormat = GL_RGB;
330       theDataType    = GL_FLOAT;
331       return true;
332     case Image_PixMap::ImgBGRF:
333       thePixelFormat = GL_BGR;
334       theDataType    = GL_FLOAT;
335       return true;
336     case Image_PixMap::ImgRGBAF:
337       thePixelFormat = GL_RGBA;
338       theDataType    = GL_FLOAT;
339       return true;
340     case Image_PixMap::ImgBGRAF:
341       thePixelFormat = GL_BGRA;
342       theDataType    = GL_FLOAT;
343       return true;
344     default:
345       return false;
346   }
347 }
348
349 Standard_Boolean OpenGl_GraphicDriver::BufferDump (const Graphic3d_CView&      theCView,
350                                                    Image_PixMap&               theImage,
351                                                    const Graphic3d_BufferType& theBufferType)
352 {
353   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
354   return (aCView != NULL) && aCView->WS->BufferDump ((OpenGl_FrameBuffer* )theCView.ptrFBO, theImage, theBufferType);
355 }
356
357 Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer*         theFBOPtr,
358                                                Image_PixMap&               theImage,
359                                                const Graphic3d_BufferType& theBufferType)
360 {
361   GLenum aFormat, aType;
362   if (theImage.IsEmpty()
363    || !getDataFormat (theImage, aFormat, aType)
364    || ((theBufferType == Graphic3d_BT_Depth) && (aFormat != GL_DEPTH_COMPONENT))
365    || !Activate())
366   {
367     return Standard_False;
368   }
369
370   // bind FBO if used
371   GLint aReadBufferPrev = GL_BACK;
372   if (theFBOPtr != NULL && theFBOPtr->IsValid())
373   {
374     theFBOPtr->BindBuffer (GetGlContext());
375   }
376   else
377   {
378     glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
379     GLint aDrawBufferPrev = GL_BACK;
380     glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
381     glReadBuffer (aDrawBufferPrev);
382   }
383
384   GLint anAlignBack = 1;
385   glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack);
386   GLint anExtraBytes = (GLint )theImage.RowExtraBytes();
387   GLint anAligment   = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
388   glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
389
390   if (anExtraBytes >= anAligment)
391   {
392     // copy row by row
393     for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
394     {
395       glReadPixels (0, GLint(aRow), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
396     }
397   }
398   else
399   {
400     // read pixels
401     glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
402     theImage.SetTopDown (false); // image bottom-up in OpenGL
403   }
404
405   glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack);
406
407   if (theFBOPtr != NULL && theFBOPtr->IsValid())
408   {
409     theFBOPtr->UnbindBuffer (GetGlContext());
410   }
411   else
412   {
413     glReadBuffer (aReadBufferPrev);
414   }
415   return Standard_True;
416 }
417
418 void OpenGl_GraphicDriver::RemoveView (const Graphic3d_CView& theCView)
419 {
420   Handle(OpenGl_Context) aShareCtx = GetSharedContext();
421   if (myMapOfView.IsBound (theCView.ViewId))
422     myMapOfView.UnBind (theCView.ViewId);
423
424   if (myMapOfWS.IsBound (theCView.WsId))
425     myMapOfWS.UnBind (theCView.WsId);
426
427   if (myMapOfWS.IsEmpty() && !myMapOfStructure.IsEmpty())
428   {
429     // The last view removed but some objects still present.
430     // Release GL resources now without object destruction.
431     for (NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
432          aStructIt.More (); aStructIt.Next())
433     {
434       OpenGl_Structure* aStruct = aStructIt.ChangeValue();
435       aStruct->ReleaseGlResources (aShareCtx);
436     }
437     myTempText->Release (aShareCtx);
438     myDeviceLostFlag = Standard_True;
439   }
440
441   OpenGl_CView* aCView = (OpenGl_CView* )theCView.ptrView;
442   aCView->View->ReleaseGlResources (aShareCtx);
443   delete aCView;
444   ((Graphic3d_CView *)&theCView)->ptrView = NULL;
445 }
446
447 void OpenGl_GraphicDriver::SetLight (const Graphic3d_CView& ACView)
448 {
449   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
450   if (aCView)
451     aCView->View->SetLights(ACView.Context);
452 }
453
454 void OpenGl_GraphicDriver::SetClipPlanes (const Graphic3d_CView& theCView)
455 {
456   const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
457   if (aCView)
458   {
459     aCView->View->SetClipPlanes (theCView.Context.ClipPlanes);
460   }
461 }
462
463 void OpenGl_GraphicDriver::SetClipPlanes (const Graphic3d_CStructure& theCStructure)
464 {
465   OpenGl_Structure* aStructure = (OpenGl_Structure *)theCStructure.ptrStructure;
466   if (aStructure)
467   {
468     aStructure->SetClipPlanes (theCStructure.ClipPlanes);
469   }
470 }
471
472 void OpenGl_GraphicDriver::SetVisualisation (const Graphic3d_CView& ACView)
473 {
474   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
475   if (aCView)
476   {
477     aCView->View->SetVisualisation(ACView.Context);
478     aCView->WS->UseZBuffer() = ( ACView.Context.Visualization == 0? (ACView.Context.ZBufferActivity == 1) : (ACView.Context.ZBufferActivity != 0) );
479   }
480 }
481
482 void OpenGl_GraphicDriver::TransformStructure (const Graphic3d_CStructure& ACStructure)
483 {
484   OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
485   if (astructure)
486     astructure->SetTransformation(&(ACStructure.Transformation[0][0]));
487 }
488
489 void OpenGl_GraphicDriver::Transparency (const Graphic3d_CView& ACView, const Standard_Boolean AFlag)
490 {
491   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
492   if (aCView)
493     aCView->WS->UseTransparency(AFlag);
494 }
495
496 void OpenGl_GraphicDriver::Update (const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACUnderLayer, const Aspect_CLayer2d& ACOverLayer)
497 {
498   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
499   if (aCView)
500     aCView->WS->Update(ACView,ACUnderLayer,ACOverLayer);
501 }
502
503 Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& theCView)
504 {
505   if (openglDisplay.IsNull())
506     return Standard_False;
507
508   if (myMapOfView.IsBound (theCView.ViewId))
509     myMapOfView.UnBind (theCView.ViewId);
510
511   if (myMapOfWS.IsBound (theCView.WsId))
512     myMapOfWS.UnBind (theCView.WsId);
513
514   Handle(OpenGl_Workspace) aWS = Handle(OpenGl_Workspace)::DownCast(openglDisplay->GetWindow (theCView.DefWindow.XWindow));
515   if (aWS.IsNull())
516   {
517     Handle(OpenGl_Context) aShareCtx = GetSharedContext();
518     aWS = new OpenGl_Workspace (openglDisplay, theCView.DefWindow, theCView.GContext, myCaps, aShareCtx);
519     openglDisplay->SetWindow (theCView.DefWindow.XWindow, aWS);
520   }
521
522   myMapOfWS.Bind (theCView.WsId, aWS);
523
524   Handle(OpenGl_View) aView = new OpenGl_View (theCView.Context);
525   myMapOfView.Bind (theCView.ViewId, aView);
526
527   OpenGl_CView* aCView = new OpenGl_CView();
528   aCView->View = aView;
529   aCView->WS = aWS;
530   theCView.ptrView = aCView;
531
532   return Standard_True;
533 }
534
535 void OpenGl_GraphicDriver::ViewMapping (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
536 {
537   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
538   if (aCView)
539   {
540     aCView->View->SetMapping(ACView);
541     if (!AWait)
542     {
543       aCView->WS->Resize(ACView.DefWindow);
544     }
545   }
546 }
547
548 void OpenGl_GraphicDriver::ViewOrientation (const Graphic3d_CView& ACView, const Standard_Boolean AWait)
549 {
550   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
551   if (aCView)
552   {
553     aCView->View->SetOrientation(ACView);
554     if (!AWait)
555     {
556       aCView->WS->Resize(ACView.DefWindow);
557     }
558   }
559 }
560
561 void OpenGl_GraphicDriver::SetBackFacingModel (const Graphic3d_CView& ACView)
562 {
563   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
564   if (aCView)
565     aCView->View->SetBackfacing(ACView.Backfacing);
566 }
567
568 //=======================================================================
569 //function : AddZLayer
570 //purpose  :
571 //=======================================================================
572
573 void OpenGl_GraphicDriver::AddZLayer (const Graphic3d_CView& theCView,
574                                       const Standard_Integer theLayerId)
575 {
576   const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
577   if (aCView)
578     aCView->View->AddZLayer (theLayerId);
579 }
580
581 //=======================================================================
582 //function : RemoveZLayer
583 //purpose  :
584 //=======================================================================
585
586 void OpenGl_GraphicDriver::RemoveZLayer (const Graphic3d_CView& theCView,
587                                          const Standard_Integer theLayerId)
588 {
589   const OpenGl_CView* aCView = (const OpenGl_CView *)theCView.ptrView;
590   if (aCView)
591     aCView->View->RemoveZLayer (theLayerId);
592 }