0024394: Visualization - implement more general way for rendering of immediate objects
[occt.git] / src / OpenGl / OpenGl_GraphicDriver.cxx
1 // Created on: 2011-10-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2013 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 <OpenGl_GraphicDriver.hxx>
17 #include <OpenGl_Context.hxx>
18 #include <OpenGl_Flipper.hxx>
19 #include <OpenGl_GraduatedTrihedron.hxx>
20 #include <OpenGl_Group.hxx>
21 #include <OpenGl_CView.hxx>
22 #include <OpenGl_View.hxx>
23 #include <OpenGl_StencilTest.hxx>
24 #include <OpenGl_Text.hxx>
25 #include <OpenGl_Trihedron.hxx>
26 #include <OpenGl_Workspace.hxx>
27
28 #include <Aspect_GraphicDeviceDefinitionError.hxx>
29 #include <Message_Messenger.hxx>
30 #include <OSD_Environment.hxx>
31 #include <Standard_NotImplemented.hxx>
32
33 #if !defined(_WIN32) && !defined(__ANDROID__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
34   #include <X11/Xlib.h> // XOpenDisplay()
35 #endif
36
37 #if defined(HAVE_EGL) || defined(__ANDROID__)
38   #include <EGL/egl.h>
39 #endif
40
41 IMPLEMENT_STANDARD_HANDLE(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
42 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
43
44 namespace
45 {
46   static const Handle(OpenGl_Context) TheNullGlCtx;
47 }
48
49 // =======================================================================
50 // function : OpenGl_GraphicDriver
51 // purpose  :
52 // =======================================================================
53 OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnection)& theDisp,
54                                             const Standard_Boolean                  theToInitialize)
55 : Graphic3d_GraphicDriver (theDisp),
56   myIsOwnContext (Standard_False),
57 #if defined(HAVE_EGL) || defined(__ANDROID__)
58   myEglDisplay ((Aspect_Display )EGL_NO_DISPLAY),
59   myEglContext ((Aspect_RenderingContext )EGL_NO_CONTEXT),
60   myEglConfig  (NULL),
61 #endif
62   myCaps           (new OpenGl_Caps()),
63   myMapOfView      (1, NCollection_BaseAllocator::CommonBaseAllocator()),
64   myMapOfWS        (1, NCollection_BaseAllocator::CommonBaseAllocator()),
65   myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator()),
66   myUserDrawCallback (NULL),
67   myTempText (new OpenGl_Text())
68 {
69 #if !defined(_WIN32) && !defined(__ANDROID__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
70   if (myDisplayConnection.IsNull())
71   {
72     //Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: cannot connect to X server!");
73     return;
74   }
75
76   Display* aDisplay = myDisplayConnection->GetDisplay();
77   Bool toSync = ::getenv ("CSF_GraphicSync") != NULL
78              || ::getenv ("CALL_SYNCHRO_X")  != NULL;
79   XSynchronize (aDisplay, toSync);
80
81 #if !defined(HAVE_EGL)
82   // does the server know about OpenGL & GLX?
83   int aDummy;
84   if (!XQueryExtension (aDisplay, "GLX", &aDummy, &aDummy, &aDummy))
85   {
86     ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, this system doesn't appear to support OpenGL!", Message_Warning);
87   }
88 #endif
89 #endif
90   if (theToInitialize
91   && !InitContext())
92   {
93     Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: default context can not be initialized!");
94   }
95 }
96
97 // =======================================================================
98 // function : ~OpenGl_GraphicDriver
99 // purpose  :
100 // =======================================================================
101 OpenGl_GraphicDriver::~OpenGl_GraphicDriver()
102 {
103   ReleaseContext();
104 }
105
106 // =======================================================================
107 // function : ReleaseContext
108 // purpose  :
109 // =======================================================================
110 void OpenGl_GraphicDriver::ReleaseContext()
111 {
112   Handle(OpenGl_Context) aCtxShared;
113   for (NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>::Iterator aWindowIter (myMapOfWS);
114        aWindowIter.More(); aWindowIter.Next())
115   {
116     const Handle(OpenGl_Workspace)& aWindow = aWindowIter.ChangeValue();
117     const Handle(OpenGl_Context)&   aCtx    = aWindow->GetGlContext();
118     if (aCtx->MakeCurrent()
119      && aCtxShared.IsNull())
120     {
121       aCtxShared = aCtx;
122     }
123   }
124
125   if (!aCtxShared.IsNull())
126   {
127     aCtxShared->MakeCurrent();
128   }
129   for (NCollection_DataMap<Standard_Integer, Handle(OpenGl_View)>::Iterator aViewIter (myMapOfView);
130        aViewIter.More(); aViewIter.Next())
131   {
132     const Handle(OpenGl_View)& aView = aViewIter.ChangeValue();
133     aView->ReleaseGlResources (aCtxShared);
134   }
135
136   for (NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
137        aStructIt.More (); aStructIt.Next())
138   {
139     OpenGl_Structure* aStruct = aStructIt.ChangeValue();
140     aStruct->ReleaseGlResources (aCtxShared);
141   }
142   myTempText->Release (aCtxShared.operator->());
143   myDeviceLostFlag = myDeviceLostFlag || !myMapOfStructure.IsEmpty();
144
145   for (NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>::Iterator aWindowIter (myMapOfWS);
146        aWindowIter.More(); aWindowIter.Next())
147   {
148     const Handle(OpenGl_Workspace)& aWindow = aWindowIter.ChangeValue();
149     const Handle(OpenGl_Context)&   aCtx    = aWindow->GetGlContext();
150     aCtx->forcedRelease();
151   }
152
153 #if defined(HAVE_EGL) || defined(__ANDROID__)
154   if (myIsOwnContext)
155   {
156     if (myEglContext != (Aspect_RenderingContext )EGL_NO_CONTEXT)
157     {
158       if (eglMakeCurrent ((EGLDisplay )myEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE)
159       {
160         ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, FAILED to release OpenGL context!", Message_Warning);
161       }
162       eglDestroyContext ((EGLDisplay )myEglDisplay, (EGLContext )myEglContext);
163     }
164
165     if (myEglDisplay != (Aspect_Display )EGL_NO_DISPLAY)
166     {
167       if (eglTerminate ((EGLDisplay )myEglDisplay) != EGL_TRUE)
168       {
169         ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, EGL, eglTerminate FAILED!", Message_Warning);
170       }
171     }
172   }
173
174   myEglDisplay = (Aspect_Display )EGL_NO_DISPLAY;
175   myEglContext = (Aspect_RenderingContext )EGL_NO_CONTEXT;
176   myEglConfig  = NULL;
177 #endif
178   myIsOwnContext = Standard_False;
179 }
180
181 // =======================================================================
182 // function : InitContext
183 // purpose  :
184 // =======================================================================
185 Standard_Boolean OpenGl_GraphicDriver::InitContext()
186 {
187   ReleaseContext();
188 #if defined(HAVE_EGL) || defined(__ANDROID__)
189
190 #if !defined(_WIN32) && !defined(__ANDROID__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
191   if (myDisplayConnection.IsNull())
192   {
193     return Standard_False;
194   }
195   Display* aDisplay = myDisplayConnection->GetDisplay();
196   myEglDisplay = (Aspect_Display )eglGetDisplay (aDisplay);
197 #else
198   myEglDisplay = (Aspect_Display )eglGetDisplay (EGL_DEFAULT_DISPLAY);
199 #endif
200   if ((EGLDisplay )myEglDisplay == EGL_NO_DISPLAY)
201   {
202     ::Message::DefaultMessenger()->Send ("Error: no EGL display!", Message_Fail);
203     return Standard_False;
204   }
205
206   EGLint aVerMajor = 0; EGLint aVerMinor = 0;
207   if (eglInitialize ((EGLDisplay )myEglDisplay, &aVerMajor, &aVerMinor) != EGL_TRUE)
208   {
209     ::Message::DefaultMessenger()->Send ("Error: EGL display is unavailable!", Message_Fail);
210     return Standard_False;
211   }
212
213   EGLint aConfigAttribs[] =
214   {
215     EGL_RED_SIZE,     8,
216     EGL_GREEN_SIZE,   8,
217     EGL_BLUE_SIZE,    8,
218     EGL_ALPHA_SIZE,   0,
219     EGL_DEPTH_SIZE,   24,
220     EGL_STENCIL_SIZE, 8,
221   #if defined(GL_ES_VERSION_2_0)
222     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
223   #else
224     EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
225   #endif
226     EGL_NONE
227   };
228
229   EGLint aNbConfigs = 0;
230   if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE
231    || myEglConfig == NULL)
232   {
233     eglGetError();
234     aConfigAttribs[4 * 2 + 1] = 16; // try config with smaller depth buffer
235     if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE
236      || myEglConfig == NULL)
237     {
238       ::Message::DefaultMessenger()->Send ("Error: EGL does not provide compatible configurations!", Message_Fail);
239       return Standard_False;
240     }
241   }
242
243 #if defined(GL_ES_VERSION_2_0)
244   EGLint anEglCtxAttribs[] =
245   {
246     EGL_CONTEXT_CLIENT_VERSION, 2,
247     EGL_NONE
248   };
249   if (eglBindAPI (EGL_OPENGL_ES_API) != EGL_TRUE)
250   {
251     ::Message::DefaultMessenger()->Send ("Error: EGL does not provide OpenGL ES client!", Message_Fail);
252     return Standard_False;
253   }
254 #else
255   EGLint* anEglCtxAttribs = NULL;
256   if (eglBindAPI (EGL_OPENGL_API) != EGL_TRUE)
257   {
258     ::Message::DefaultMessenger()->Send ("Error: EGL does not provide OpenGL client!", Message_Fail);
259     return Standard_False;
260   }
261 #endif
262
263   myEglContext = (Aspect_RenderingContext )eglCreateContext ((EGLDisplay )myEglDisplay, myEglConfig, EGL_NO_CONTEXT, anEglCtxAttribs);
264   if ((EGLContext )myEglContext == EGL_NO_CONTEXT)
265   {
266     ::Message::DefaultMessenger()->Send ("Error: EGL is unable to create OpenGL context!", Message_Fail);
267     return Standard_False;
268   }
269   if (eglMakeCurrent ((EGLDisplay )myEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, (EGLContext )myEglContext) != EGL_TRUE)
270   {
271     ::Message::DefaultMessenger()->Send ("Error: EGL is unable bind OpenGL context!", Message_Fail);
272     return Standard_False;
273   }
274 #endif
275   myIsOwnContext = Standard_True;
276   return Standard_True;
277 }
278
279 #if defined(HAVE_EGL) || defined(__ANDROID__)
280 // =======================================================================
281 // function : InitEglContext
282 // purpose  :
283 // =======================================================================
284 Standard_Boolean OpenGl_GraphicDriver::InitEglContext (Aspect_Display          theEglDisplay,
285                                                        Aspect_RenderingContext theEglContext,
286                                                        void*                   theEglConfig)
287 {
288   ReleaseContext();
289 #if !defined(_WIN32) && !defined(__ANDROID__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
290   if (myDisplayConnection.IsNull())
291   {
292     return Standard_False;
293   }
294 #endif
295
296   if ((EGLDisplay )theEglDisplay == EGL_NO_DISPLAY
297    || (EGLContext )theEglContext == EGL_NO_CONTEXT
298    || theEglConfig == NULL)
299   {
300     return Standard_False;
301   }
302   myEglDisplay = theEglDisplay;
303   myEglContext = theEglContext;
304   myEglConfig  = theEglConfig;
305   return Standard_True;
306 }
307 #endif
308
309 // =======================================================================
310 // function : InquireLightLimit
311 // purpose  :
312 // =======================================================================
313 Standard_Integer OpenGl_GraphicDriver::InquireLightLimit()
314 {
315   return OpenGLMaxLights;
316 }
317
318 // =======================================================================
319 // function : InquireViewLimit
320 // purpose  :
321 // =======================================================================
322 Standard_Integer OpenGl_GraphicDriver::InquireViewLimit()
323 {
324   return 10000;
325 }
326
327 // =======================================================================
328 // function : InquirePlaneLimit
329 // purpose  :
330 // =======================================================================
331 Standard_Integer OpenGl_GraphicDriver::InquirePlaneLimit()
332 {
333   // NOTE the 2 first planes are reserved for ZClipping
334   const Handle(OpenGl_Context)& aCtx = GetSharedContext();
335   return aCtx.IsNull() ? 0 : Max (aCtx->MaxClipPlanes() - 2, 0);
336 }
337
338 // =======================================================================
339 // function : UserDrawCallback
340 // purpose  :
341 // =======================================================================
342 OpenGl_GraphicDriver::OpenGl_UserDrawCallback_t& OpenGl_GraphicDriver::UserDrawCallback()
343 {
344   return myUserDrawCallback;
345 }
346
347 // =======================================================================
348 // function : DefaultTextHeight
349 // purpose  :
350 // =======================================================================
351 Standard_ShortReal OpenGl_GraphicDriver::DefaultTextHeight() const
352 {
353   return 16.;
354 }
355
356 // =======================================================================
357 // function : EnableVBO
358 // purpose  :
359 // =======================================================================
360 void OpenGl_GraphicDriver::EnableVBO (const Standard_Boolean theToTurnOn)
361 {
362   myCaps->vboDisable = !theToTurnOn;
363 }
364
365 // =======================================================================
366 // function : GetSharedContext
367 // purpose  :
368 // =======================================================================
369 const Handle(OpenGl_Context)& OpenGl_GraphicDriver::GetSharedContext() const
370 {
371   if (myMapOfWS.IsEmpty())
372   {
373     return TheNullGlCtx;
374   }
375
376   NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>::Iterator anIter (myMapOfWS);
377   return anIter.Value()->GetGlContext();
378 }
379
380 // =======================================================================
381 // function : MemoryInfo
382 // purpose  :
383 // =======================================================================
384 Standard_Boolean OpenGl_GraphicDriver::MemoryInfo (Standard_Size&           theFreeBytes,
385                                                    TCollection_AsciiString& theInfo) const
386 {
387   // this is extra work (for OpenGl_Context initialization)...
388   OpenGl_Context aGlCtx;
389   if (!aGlCtx.Init())
390   {
391     return Standard_False;
392   }
393   theFreeBytes = aGlCtx.AvailableMemory();
394   theInfo      = aGlCtx.MemoryInfo();
395   return !theInfo.IsEmpty();
396 }
397
398 // =======================================================================
399 // function : SetImmediateModeDrawToFront
400 // purpose  :
401 // =======================================================================
402 Standard_Boolean OpenGl_GraphicDriver::SetImmediateModeDrawToFront (const Graphic3d_CView& theCView,
403                                                                     const Standard_Boolean theDrawToFrontBuffer)
404 {
405   if (theCView.ViewId == -1)
406   {
407     return Standard_False;
408   }
409
410   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
411   if (aCView != NULL)
412   {
413     return aCView->WS->SetImmediateModeDrawToFront (theDrawToFrontBuffer);
414   }
415   return Standard_False;
416 }
417
418 // =======================================================================
419 // function : DisplayImmediateStructure
420 // purpose  :
421 // =======================================================================
422 void OpenGl_GraphicDriver::DisplayImmediateStructure (const Graphic3d_CView&             theCView,
423                                                       const Handle(Graphic3d_Structure)& theStructure)
424 {
425   OpenGl_CView* aCView = (OpenGl_CView* )theCView.ptrView;
426   if (aCView == NULL)
427   {
428     return;
429   }
430
431   aCView->View->DisplayImmediateStructure (theStructure);
432 }
433
434 // =======================================================================
435 // function : EraseImmediateStructure
436 // purpose  :
437 // =======================================================================
438 void OpenGl_GraphicDriver::EraseImmediateStructure (const Graphic3d_CView&      theCView,
439                                                     const Graphic3d_CStructure& theCStructure)
440 {
441   OpenGl_CView*     aCView     = (OpenGl_CView*     )theCView.ptrView;
442   OpenGl_Structure* aStructure = (OpenGl_Structure* )&theCStructure;
443   if (aCView == NULL)
444   {
445     return;
446   }
447
448   aCView->View->EraseImmediateStructure (aStructure);
449 }
450
451
452 // =======================================================================
453 // function : Print
454 // purpose  :
455 // =======================================================================
456 Standard_Boolean OpenGl_GraphicDriver::Print (const Graphic3d_CView& theCView,
457                                               const Aspect_CLayer2d& theCUnderLayer,
458                                               const Aspect_CLayer2d& theCOverLayer,
459                                               const Aspect_Handle    thePrintDC,
460                                               const Standard_Boolean theToShowBackground,
461                                               const Standard_CString theFilename,
462                                               const Aspect_PrintAlgo thePrintAlgorithm,
463                                               const Standard_Real    theScaleFactor) const
464 {
465   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
466   if (aCView == NULL
467    || !myPrintContext.IsNull())
468   {
469     return Standard_False;
470   }
471
472   Standard_Boolean isPrinted = Standard_False;
473   myPrintContext = new OpenGl_PrinterContext();
474 #ifdef _WIN32
475   isPrinted = aCView->WS->Print (myPrintContext,
476                                  theCView,
477                                  theCUnderLayer,
478                                  theCOverLayer,
479                                  thePrintDC,
480                                  theToShowBackground,
481                                  theFilename,
482                                  thePrintAlgorithm,
483                                  theScaleFactor);
484 #else
485   Standard_NotImplemented::Raise ("OpenGl_GraphicDriver::Print is implemented only on Windows");
486 #endif
487   myPrintContext.Nullify();
488   return isPrinted;
489 }
490
491 // =======================================================================
492 // function : ZBufferTriedronSetup
493 // purpose  :
494 // =======================================================================
495 void OpenGl_GraphicDriver::ZBufferTriedronSetup (const Quantity_NameOfColor theXColor,
496                                                  const Quantity_NameOfColor theYColor,
497                                                  const Quantity_NameOfColor theZColor,
498                                                  const Standard_Real        theSizeRatio,
499                                                  const Standard_Real        theAxisDiametr,
500                                                  const Standard_Integer     theNbFacettes)
501 {
502   OpenGl_Trihedron::Setup (theXColor, theYColor, theZColor, theSizeRatio, theAxisDiametr, theNbFacettes);
503 }
504
505 // =======================================================================
506 // function : TriedronDisplay
507 // purpose  :
508 // =======================================================================
509 void OpenGl_GraphicDriver::TriedronDisplay (const Graphic3d_CView&              theCView,
510                                             const Aspect_TypeOfTriedronPosition thePosition,
511                                             const Quantity_NameOfColor          theColor,
512                                             const Standard_Real                 theScale,
513                                             const Standard_Boolean              theAsWireframe)
514 {
515   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
516   if (aCView != NULL)
517   {
518     aCView->View->TriedronDisplay (aCView->WS->GetGlContext(), thePosition, theColor, theScale, theAsWireframe);
519   }
520 }
521
522 // =======================================================================
523 // function : TriedronErase
524 // purpose  :
525 // =======================================================================
526 void OpenGl_GraphicDriver::TriedronErase (const Graphic3d_CView& theCView)
527 {
528   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
529   if (aCView != NULL)
530   {
531     aCView->View->TriedronErase (aCView->WS->GetGlContext());
532   }
533 }
534
535 // =======================================================================
536 // function : TriedronEcho
537 // purpose  :
538 // =======================================================================
539 void OpenGl_GraphicDriver::TriedronEcho (const Graphic3d_CView& ,
540                                          const Aspect_TypeOfTriedronEcho )
541 {
542   // do nothing
543 }
544
545 // =======================================================================
546 // function : Environment
547 // purpose  :
548 // =======================================================================
549 void OpenGl_GraphicDriver::Environment (const Graphic3d_CView& theCView)
550 {
551   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
552   if (aCView == NULL)
553   {
554     return;
555   }
556
557   aCView->View->SetTextureEnv    (aCView->WS->GetGlContext(), theCView.Context.TextureEnv);
558   aCView->View->SetSurfaceDetail ((Visual3d_TypeOfSurfaceDetail)theCView.Context.SurfaceDetail);
559 }
560
561 // =======================================================================
562 // function : BackgroundImage
563 // purpose  :
564 // =======================================================================
565 void OpenGl_GraphicDriver::BackgroundImage (const Standard_CString  theFileName,
566                                             const Graphic3d_CView&  theCView,
567                                             const Aspect_FillMethod theFillStyle)
568 {
569   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
570   if (aCView != NULL)
571   {
572     aCView->View->CreateBackgroundTexture (theFileName, theFillStyle);
573   }
574 }
575
576 // =======================================================================
577 // function : SetBgImageStyle
578 // purpose  :
579 // =======================================================================
580 void OpenGl_GraphicDriver::SetBgImageStyle (const Graphic3d_CView&  theCView,
581                                             const Aspect_FillMethod theFillStyle)
582 {
583   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
584   if (aCView != NULL)
585   {
586     aCView->View->SetBackgroundTextureStyle (theFillStyle);
587   }
588 }
589
590 // =======================================================================
591 // function : SetBgGradientStyle
592 // purpose  :
593 // =======================================================================
594 void OpenGl_GraphicDriver::SetBgGradientStyle (const Graphic3d_CView&          theCView,
595                                                const Aspect_GradientFillMethod theFillType)
596 {
597   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
598   if (aCView != NULL)
599   {
600     aCView->View->SetBackgroundGradientType (theFillType);
601   }
602 }
603
604 // =======================================================================
605 // function : GraduatedTrihedronDisplay
606 // purpose  :
607 // =======================================================================
608 void OpenGl_GraphicDriver::GraduatedTrihedronDisplay (const Graphic3d_CView&               theCView,
609                                                       const Graphic3d_CGraduatedTrihedron& theCubic)
610 {
611   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
612   if (aCView != NULL)
613   {
614     aCView->View->GraduatedTrihedronDisplay (aCView->WS->GetGlContext(), theCubic);
615   }
616 }
617
618 // =======================================================================
619 // function : GraduatedTrihedronErase
620 // purpose  :
621 // =======================================================================
622 void OpenGl_GraphicDriver::GraduatedTrihedronErase (const Graphic3d_CView& theCView)
623 {
624   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
625   if (aCView != NULL)
626   {
627     aCView->View->GraduatedTrihedronErase (aCView->WS->GetGlContext());
628   }
629 }
630
631 // =======================================================================
632 // function : GraduatedTrihedronMinMaxValues
633 // purpose  :
634 // =======================================================================
635 void OpenGl_GraphicDriver::GraduatedTrihedronMinMaxValues (const Standard_ShortReal theMinX,
636                                                            const Standard_ShortReal theMinY,
637                                                            const Standard_ShortReal theMinZ,
638                                                            const Standard_ShortReal theMaxX,
639                                                            const Standard_ShortReal theMaxY,
640                                                            const Standard_ShortReal theMaxZ)
641 {
642   OpenGl_GraduatedTrihedron::SetMinMax (theMinX, theMinY, theMinZ, theMaxX, theMaxY, theMaxZ);
643 }