1 // Created on: 2011-10-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2013 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
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>
28 #include <Aspect_GraphicDeviceDefinitionError.hxx>
29 #include <Message_Messenger.hxx>
30 #include <OSD_Environment.hxx>
31 #include <Standard_NotImplemented.hxx>
33 #if !defined(_WIN32) && !defined(__ANDROID__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
34 #include <X11/Xlib.h> // XOpenDisplay()
37 #if defined(HAVE_EGL) || defined(__ANDROID__)
41 IMPLEMENT_STANDARD_HANDLE(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
42 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
46 static const Handle(OpenGl_Context) TheNullGlCtx;
49 // =======================================================================
50 // function : OpenGl_GraphicDriver
52 // =======================================================================
53 OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnection)& theDisp,
54 const Standard_Boolean theToStealActiveContext)
55 : Graphic3d_GraphicDriver (theDisp),
56 #if defined(HAVE_EGL) || defined(__ANDROID__)
57 myEglDisplay ((Aspect_Display )EGL_NO_DISPLAY),
58 myEglContext ((Aspect_RenderingContext )EGL_NO_CONTEXT),
61 myCaps (new OpenGl_Caps()),
62 myMapOfView (1, NCollection_BaseAllocator::CommonBaseAllocator()),
63 myMapOfWS (1, NCollection_BaseAllocator::CommonBaseAllocator()),
64 myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator()),
65 myUserDrawCallback (NULL),
66 myTempText (new OpenGl_Text())
68 #if !defined(_WIN32) && !defined(__ANDROID__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
69 if (myDisplayConnection.IsNull())
71 //Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: cannot connect to X server!");
75 Display* aDisplay = myDisplayConnection->GetDisplay();
76 Bool toSync = ::getenv ("CSF_GraphicSync") != NULL
77 || ::getenv ("CALL_SYNCHRO_X") != NULL;
78 XSynchronize (aDisplay, toSync);
80 #if !defined(HAVE_EGL)
81 // does the server know about OpenGL & GLX?
83 if (!XQueryExtension (aDisplay, "GLX", &aDummy, &aDummy, &aDummy))
86 std::cerr << "This system doesn't appear to support OpenGL\n";
92 #if defined(HAVE_EGL) || defined(__ANDROID__)
93 if (theToStealActiveContext)
95 myEglDisplay = (Aspect_Display )eglGetCurrentDisplay();
96 myEglContext = (Aspect_RenderingContext )eglGetCurrentContext();
97 EGLSurface aEglSurf = eglGetCurrentSurface(EGL_DRAW);
98 if ((EGLDisplay )myEglDisplay == EGL_NO_DISPLAY
99 || (EGLContext )myEglContext == EGL_NO_CONTEXT)
101 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: no active EGL context to steal!");
105 TCollection_AsciiString anEglInfo = TCollection_AsciiString()
107 + "\n Version: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_VERSION)
108 + "\n Vendor: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_VENDOR)
109 + "\n Client APIs: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_CLIENT_APIS)
110 + "\n Extensions: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_EXTENSIONS);
111 ::Message::DefaultMessenger()->Send (anEglInfo, Message_Info);
114 eglQuerySurface((EGLDisplay )myEglDisplay, aEglSurf, EGL_CONFIG_ID, &aCfgId);
115 const EGLint aConfigAttribs[] =
117 EGL_CONFIG_ID, aCfgId,
121 EGLint aNbConfigs = 0;
122 if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE)
124 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL does not provide compatible configurations!");
129 #if !defined(_WIN32) && !defined(__ANDROID__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
130 myEglDisplay = (Aspect_Display )eglGetDisplay (aDisplay);
132 myEglDisplay = (Aspect_Display )eglGetDisplay (EGL_DEFAULT_DISPLAY);
134 if ((EGLDisplay )myEglDisplay == EGL_NO_DISPLAY)
136 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: no EGL display!");
140 EGLint aVerMajor = 0; EGLint aVerMinor = 0;
141 if (eglInitialize ((EGLDisplay )myEglDisplay, &aVerMajor, &aVerMinor) != EGL_TRUE)
143 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL display is unavailable!");
147 TCollection_AsciiString anEglInfo = TCollection_AsciiString()
149 + "\n Version: " + aVerMajor + "." + aVerMinor + " (" + eglQueryString ((EGLDisplay )myEglDisplay, EGL_VERSION)
150 + "\n Vendor: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_VENDOR)
151 + "\n Client APIs: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_CLIENT_APIS)
152 + "\n Extensions: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_EXTENSIONS);
153 ::Message::DefaultMessenger()->Send (anEglInfo, Message_Info);
155 const EGLint aConfigAttribs[] =
163 #if defined(GL_ES_VERSION_2_0)
164 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
166 EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
171 EGLint aNbConfigs = 0;
172 if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE)
174 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL does not provide compatible configurations!");
178 #if defined(GL_ES_VERSION_2_0)
179 if (eglBindAPI (EGL_OPENGL_ES_API) != EGL_TRUE)
181 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL does not provide OpenGL ES client!");
185 if (eglBindAPI (EGL_OPENGL_API) != EGL_TRUE)
187 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL does not provide OpenGL client!");
192 #if defined(GL_ES_VERSION_2_0)
193 EGLint anEglCtxAttribs[] =
195 EGL_CONTEXT_CLIENT_VERSION, 2,
199 EGLint* anEglCtxAttribs = NULL;
202 myEglContext = (Aspect_RenderingContext )eglCreateContext ((EGLDisplay )myEglDisplay, myEglConfig, EGL_NO_CONTEXT, anEglCtxAttribs);
203 if ((EGLContext )myEglContext == EGL_NO_CONTEXT)
205 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL is unable to create OpenGL context!");
208 if (eglMakeCurrent ((EGLDisplay )myEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, (EGLContext )myEglContext) != EGL_TRUE)
210 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL is unable bind OpenGL context!");
214 // not yet implemented
215 (void )theToStealActiveContext;
219 // =======================================================================
220 // function : InquireLightLimit
222 // =======================================================================
223 Standard_Integer OpenGl_GraphicDriver::InquireLightLimit()
225 return OpenGLMaxLights;
228 // =======================================================================
229 // function : InquireViewLimit
231 // =======================================================================
232 Standard_Integer OpenGl_GraphicDriver::InquireViewLimit()
237 // =======================================================================
238 // function : InquirePlaneLimit
240 // =======================================================================
241 Standard_Integer OpenGl_GraphicDriver::InquirePlaneLimit()
243 // NOTE the 2 first planes are reserved for ZClipping
244 const Handle(OpenGl_Context)& aCtx = GetSharedContext();
245 return aCtx.IsNull() ? 0 : Max (aCtx->MaxClipPlanes() - 2, 0);
248 // =======================================================================
249 // function : UserDrawCallback
251 // =======================================================================
252 OpenGl_GraphicDriver::OpenGl_UserDrawCallback_t& OpenGl_GraphicDriver::UserDrawCallback()
254 return myUserDrawCallback;
257 // =======================================================================
258 // function : DefaultTextHeight
260 // =======================================================================
261 Standard_ShortReal OpenGl_GraphicDriver::DefaultTextHeight() const
266 // =======================================================================
267 // function : EnableVBO
269 // =======================================================================
270 void OpenGl_GraphicDriver::EnableVBO (const Standard_Boolean theToTurnOn)
272 myCaps->vboDisable = !theToTurnOn;
275 // =======================================================================
276 // function : GetSharedContext
278 // =======================================================================
279 const Handle(OpenGl_Context)& OpenGl_GraphicDriver::GetSharedContext() const
281 if (myMapOfWS.IsEmpty())
286 NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>::Iterator anIter (myMapOfWS);
287 return anIter.Value()->GetGlContext();
290 // =======================================================================
291 // function : MemoryInfo
293 // =======================================================================
294 Standard_Boolean OpenGl_GraphicDriver::MemoryInfo (Standard_Size& theFreeBytes,
295 TCollection_AsciiString& theInfo) const
297 // this is extra work (for OpenGl_Context initialization)...
298 OpenGl_Context aGlCtx;
301 return Standard_False;
303 theFreeBytes = aGlCtx.AvailableMemory();
304 theInfo = aGlCtx.MemoryInfo();
305 return !theInfo.IsEmpty();
308 // =======================================================================
309 // function : SetImmediateModeDrawToFront
311 // =======================================================================
312 Standard_Boolean OpenGl_GraphicDriver::SetImmediateModeDrawToFront (const Graphic3d_CView& theCView,
313 const Standard_Boolean theDrawToFrontBuffer)
315 if (theCView.ViewId == -1)
317 return Standard_False;
320 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
323 return aCView->WS->SetImmediateModeDrawToFront (theDrawToFrontBuffer);
325 return Standard_False;
328 // =======================================================================
329 // function : DisplayImmediateStructure
331 // =======================================================================
332 void OpenGl_GraphicDriver::DisplayImmediateStructure (const Graphic3d_CView& theCView,
333 const Graphic3d_CStructure& theCStructure)
335 OpenGl_CView* aCView = (OpenGl_CView* )theCView.ptrView;
336 OpenGl_Structure* aStructure = (OpenGl_Structure* )&theCStructure;
342 aCView->View->DisplayImmediateStructure (aStructure);
345 // =======================================================================
346 // function : EraseImmediateStructure
348 // =======================================================================
349 void OpenGl_GraphicDriver::EraseImmediateStructure (const Graphic3d_CView& theCView,
350 const Graphic3d_CStructure& theCStructure)
352 OpenGl_CView* aCView = (OpenGl_CView* )theCView.ptrView;
353 OpenGl_Structure* aStructure = (OpenGl_Structure* )&theCStructure;
359 aCView->View->EraseImmediateStructure (aStructure);
363 // =======================================================================
366 // =======================================================================
367 Standard_Boolean OpenGl_GraphicDriver::Print (const Graphic3d_CView& theCView,
368 const Aspect_CLayer2d& theCUnderLayer,
369 const Aspect_CLayer2d& theCOverLayer,
370 const Aspect_Handle thePrintDC,
371 const Standard_Boolean theToShowBackground,
372 const Standard_CString theFilename,
373 const Aspect_PrintAlgo thePrintAlgorithm,
374 const Standard_Real theScaleFactor) const
376 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
378 || !myPrintContext.IsNull())
380 return Standard_False;
383 Standard_Boolean isPrinted = Standard_False;
384 myPrintContext = new OpenGl_PrinterContext();
386 isPrinted = aCView->WS->Print (myPrintContext,
396 Standard_NotImplemented::Raise ("OpenGl_GraphicDriver::Print is implemented only on Windows");
398 myPrintContext.Nullify();
402 // =======================================================================
403 // function : ZBufferTriedronSetup
405 // =======================================================================
406 void OpenGl_GraphicDriver::ZBufferTriedronSetup (const Quantity_NameOfColor theXColor,
407 const Quantity_NameOfColor theYColor,
408 const Quantity_NameOfColor theZColor,
409 const Standard_Real theSizeRatio,
410 const Standard_Real theAxisDiametr,
411 const Standard_Integer theNbFacettes)
413 OpenGl_Trihedron::Setup (theXColor, theYColor, theZColor, theSizeRatio, theAxisDiametr, theNbFacettes);
416 // =======================================================================
417 // function : TriedronDisplay
419 // =======================================================================
420 void OpenGl_GraphicDriver::TriedronDisplay (const Graphic3d_CView& theCView,
421 const Aspect_TypeOfTriedronPosition thePosition,
422 const Quantity_NameOfColor theColor,
423 const Standard_Real theScale,
424 const Standard_Boolean theAsWireframe)
426 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
429 aCView->View->TriedronDisplay (aCView->WS->GetGlContext(), thePosition, theColor, theScale, theAsWireframe);
433 // =======================================================================
434 // function : TriedronErase
436 // =======================================================================
437 void OpenGl_GraphicDriver::TriedronErase (const Graphic3d_CView& theCView)
439 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
442 aCView->View->TriedronErase (aCView->WS->GetGlContext());
446 // =======================================================================
447 // function : TriedronEcho
449 // =======================================================================
450 void OpenGl_GraphicDriver::TriedronEcho (const Graphic3d_CView& ,
451 const Aspect_TypeOfTriedronEcho )
456 // =======================================================================
457 // function : Environment
459 // =======================================================================
460 void OpenGl_GraphicDriver::Environment (const Graphic3d_CView& theCView)
462 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
468 aCView->View->SetTextureEnv (aCView->WS->GetGlContext(), theCView.Context.TextureEnv);
469 aCView->View->SetSurfaceDetail ((Visual3d_TypeOfSurfaceDetail)theCView.Context.SurfaceDetail);
472 // =======================================================================
473 // function : BackgroundImage
475 // =======================================================================
476 void OpenGl_GraphicDriver::BackgroundImage (const Standard_CString theFileName,
477 const Graphic3d_CView& theCView,
478 const Aspect_FillMethod theFillStyle)
480 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
483 aCView->View->CreateBackgroundTexture (theFileName, theFillStyle);
487 // =======================================================================
488 // function : SetBgImageStyle
490 // =======================================================================
491 void OpenGl_GraphicDriver::SetBgImageStyle (const Graphic3d_CView& theCView,
492 const Aspect_FillMethod theFillStyle)
494 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
497 aCView->View->SetBackgroundTextureStyle (theFillStyle);
501 // =======================================================================
502 // function : SetBgGradientStyle
504 // =======================================================================
505 void OpenGl_GraphicDriver::SetBgGradientStyle (const Graphic3d_CView& theCView,
506 const Aspect_GradientFillMethod theFillType)
508 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
511 aCView->View->SetBackgroundGradientType (theFillType);
515 // =======================================================================
516 // function : GraduatedTrihedronDisplay
518 // =======================================================================
519 void OpenGl_GraphicDriver::GraduatedTrihedronDisplay (const Graphic3d_CView& theCView,
520 const Graphic3d_CGraduatedTrihedron& theCubic)
522 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
525 aCView->View->GraduatedTrihedronDisplay (aCView->WS->GetGlContext(), theCubic);
529 // =======================================================================
530 // function : GraduatedTrihedronErase
532 // =======================================================================
533 void OpenGl_GraphicDriver::GraduatedTrihedronErase (const Graphic3d_CView& theCView)
535 const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
538 aCView->View->GraduatedTrihedronErase (aCView->WS->GetGlContext());
542 // =======================================================================
543 // function : GraduatedTrihedronMinMaxValues
545 // =======================================================================
546 void OpenGl_GraphicDriver::GraduatedTrihedronMinMaxValues (const Standard_ShortReal theMinX,
547 const Standard_ShortReal theMinY,
548 const Standard_ShortReal theMinZ,
549 const Standard_ShortReal theMaxX,
550 const Standard_ShortReal theMaxY,
551 const Standard_ShortReal theMaxZ)
553 OpenGl_GraduatedTrihedron::SetMinMax (theMinX, theMinY, theMinZ, theMaxX, theMaxY, theMaxZ);