699065636ea340cbb5dfca3b0ee3ad1a79cdfff1
[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 #ifdef HAVE_CONFIG_H
17   #include <config.h>
18 #endif
19
20 #include <OpenGl_GraphicDriver.hxx>
21 #include <OpenGl_Context.hxx>
22 #include <OpenGl_Flipper.hxx>
23 #include <OpenGl_GraduatedTrihedron.hxx>
24 #include <OpenGl_Group.hxx>
25 #include <OpenGl_CView.hxx>
26 #include <OpenGl_View.hxx>
27 #include <OpenGl_StencilTest.hxx>
28 #include <OpenGl_Text.hxx>
29 #include <OpenGl_Trihedron.hxx>
30 #include <OpenGl_Workspace.hxx>
31
32 #include <OSD_Environment.hxx>
33 #include <Standard_NotImplemented.hxx>
34
35 #if (!defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)))
36   #include <X11/Xlib.h> // XOpenDisplay()
37 #endif
38
39 IMPLEMENT_STANDARD_HANDLE(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
40 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
41
42 namespace
43 {
44   static const Handle(OpenGl_Context) TheNullGlCtx;
45 };
46
47 // Pour eviter de "mangler" MetaGraphicDriverFactory, le nom de la
48 // fonction qui cree un Graphic3d_GraphicDriver.
49 // En effet, ce nom est recherche par la methode DlSymb de la
50 // classe OSD_SharedLibrary dans la methode SetGraphicDriver de la
51 // classe Graphic3d_GraphicDevice
52 extern "C" {
53 #if defined(_MSC_VER) // disable MS VC++ warning on C-style function returning C++ object
54   #pragma warning(push)
55   #pragma warning(disable:4190)
56 #endif
57   Standard_EXPORT Handle(Graphic3d_GraphicDriver) MetaGraphicDriverFactory (const Standard_CString theShrName)
58   {
59     Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver (theShrName);
60     return aDriver;
61   }
62 #if defined(_MSC_VER)
63   #pragma warning(pop)
64 #endif
65 }
66
67 // =======================================================================
68 // function : OpenGl_GraphicDriver
69 // purpose  :
70 // =======================================================================
71 OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
72 : Graphic3d_GraphicDriver ("TKOpenGl"),
73   myCaps           (new OpenGl_Caps()),
74   myMapOfView      (1, NCollection_BaseAllocator::CommonBaseAllocator()),
75   myMapOfWS        (1, NCollection_BaseAllocator::CommonBaseAllocator()),
76   myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator()),
77   myUserDrawCallback (NULL),
78   myTempText (new OpenGl_Text())
79 {
80   Begin (theDisplayConnection);
81 }
82
83 // =======================================================================
84 // function : OpenGl_GraphicDriver
85 // purpose  :
86 // =======================================================================
87 OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Standard_CString theShrName)
88 : Graphic3d_GraphicDriver (theShrName),
89   myCaps           (new OpenGl_Caps()),
90   myMapOfView      (1, NCollection_BaseAllocator::CommonBaseAllocator()),
91   myMapOfWS        (1, NCollection_BaseAllocator::CommonBaseAllocator()),
92   myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator()),
93   myUserDrawCallback (NULL),
94   myTempText (new OpenGl_Text())
95 {
96   //
97 }
98
99 // =======================================================================
100 // function : Begin
101 // purpose  :
102 // =======================================================================
103 Standard_Boolean OpenGl_GraphicDriver::Begin (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
104 {
105   myDisplayConnection = theDisplayConnection;
106   if (myDisplayConnection.IsNull())
107   {
108   #if (!defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)))
109     //Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: cannot connect to X server!");
110     return Standard_False;
111   #else
112     return Standard_True;
113   #endif
114   }
115
116 #if (!defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)))
117   Display* aDisplay = myDisplayConnection->GetDisplay();
118   Bool toSync = ::getenv ("CSF_GraphicSync") != NULL
119              || ::getenv ("CALL_SYNCHRO_X")  != NULL;
120   XSynchronize (aDisplay, toSync);
121
122   // does the server know about OpenGL & GLX?
123   int aDummy;
124   if (!XQueryExtension (aDisplay, "GLX", &aDummy, &aDummy, &aDummy))
125   {
126   #ifdef DEBUG
127     std::cerr << "This system doesn't appear to support OpenGL\n";
128   #endif
129   }
130 #endif
131   return Standard_True;
132 }
133
134 // =======================================================================
135 // function : End
136 // purpose  :
137 // =======================================================================
138 void OpenGl_GraphicDriver::End()
139 {
140   // deprecated method
141   ///myDisplayConnection.Nullify();
142 }
143
144 // =======================================================================
145 // function : InquireLightLimit
146 // purpose  :
147 // =======================================================================
148 Standard_Integer OpenGl_GraphicDriver::InquireLightLimit()
149 {
150   return OpenGLMaxLights;
151 }
152
153 // =======================================================================
154 // function : InquireViewLimit
155 // purpose  :
156 // =======================================================================
157 Standard_Integer OpenGl_GraphicDriver::InquireViewLimit()
158 {
159   return 10000;
160 }
161
162 // =======================================================================
163 // function : InquirePlaneLimit
164 // purpose  :
165 // =======================================================================
166 Standard_Integer OpenGl_GraphicDriver::InquirePlaneLimit()
167 {
168   // NOTE the 2 first planes are reserved for ZClipping
169   const Handle(OpenGl_Context)& aCtx = GetSharedContext();
170   return aCtx.IsNull() ? 0 : Max (aCtx->MaxClipPlanes() - 2, 0);
171 }
172
173 // =======================================================================
174 // function : UserDrawCallback
175 // purpose  :
176 // =======================================================================
177 OpenGl_GraphicDriver::OpenGl_UserDrawCallback_t& OpenGl_GraphicDriver::UserDrawCallback()
178 {
179   return myUserDrawCallback;
180 }
181
182 // =======================================================================
183 // function : DefaultTextHeight
184 // purpose  :
185 // =======================================================================
186 Standard_ShortReal OpenGl_GraphicDriver::DefaultTextHeight() const
187 {
188   return 16.;
189 }
190
191 // =======================================================================
192 // function : EnableVBO
193 // purpose  :
194 // =======================================================================
195 void OpenGl_GraphicDriver::EnableVBO (const Standard_Boolean theToTurnOn)
196 {
197   myCaps->vboDisable = !theToTurnOn;
198 }
199
200 // =======================================================================
201 // function : GetSharedContext
202 // purpose  :
203 // =======================================================================
204 const Handle(OpenGl_Context)& OpenGl_GraphicDriver::GetSharedContext() const
205 {
206   if (myMapOfWS.IsEmpty())
207   {
208     return TheNullGlCtx;
209   }
210
211   NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>::Iterator anIter (myMapOfWS);
212   return anIter.Value()->GetGlContext();
213 }
214
215 // =======================================================================
216 // function : MemoryInfo
217 // purpose  :
218 // =======================================================================
219 Standard_Boolean OpenGl_GraphicDriver::MemoryInfo (Standard_Size&           theFreeBytes,
220                                                    TCollection_AsciiString& theInfo) const
221 {
222   // this is extra work (for OpenGl_Context initialization)...
223   OpenGl_Context aGlCtx;
224   if (!aGlCtx.Init())
225   {
226     return Standard_False;
227   }
228   theFreeBytes = aGlCtx.AvailableMemory();
229   theInfo      = aGlCtx.MemoryInfo();
230   return !theInfo.IsEmpty();
231 }
232
233 // =======================================================================
234 // function : SetImmediateModeDrawToFront
235 // purpose  :
236 // =======================================================================
237 Standard_Boolean OpenGl_GraphicDriver::SetImmediateModeDrawToFront (const Graphic3d_CView& theCView,
238                                                                     const Standard_Boolean theDrawToFrontBuffer)
239 {
240   if (theCView.ViewId == -1)
241   {
242     return Standard_False;
243   }
244
245   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
246   if (aCView != NULL)
247   {
248     return aCView->WS->SetImmediateModeDrawToFront (theDrawToFrontBuffer);
249   }
250   return Standard_False;
251 }
252
253 // =======================================================================
254 // function : DisplayImmediateStructure
255 // purpose  :
256 // =======================================================================
257 void OpenGl_GraphicDriver::DisplayImmediateStructure (const Graphic3d_CView&      theCView,
258                                                       const Graphic3d_CStructure& theCStructure)
259 {
260   OpenGl_CView*     aCView     = (OpenGl_CView*     )theCView.ptrView;
261   OpenGl_Structure* aStructure = (OpenGl_Structure* )&theCStructure;
262   if (aCView == NULL)
263   {
264     return;
265   }
266
267   aCView->View->DisplayImmediateStructure (aStructure);
268 }
269
270 // =======================================================================
271 // function : EraseImmediateStructure
272 // purpose  :
273 // =======================================================================
274 void OpenGl_GraphicDriver::EraseImmediateStructure (const Graphic3d_CView&      theCView,
275                                                     const Graphic3d_CStructure& theCStructure)
276 {
277   OpenGl_CView*     aCView     = (OpenGl_CView*     )theCView.ptrView;
278   OpenGl_Structure* aStructure = (OpenGl_Structure* )&theCStructure;
279   if (aCView == NULL)
280   {
281     return;
282   }
283
284   aCView->View->EraseImmediateStructure (aStructure);
285 }
286
287
288 // =======================================================================
289 // function : Print
290 // purpose  :
291 // =======================================================================
292 Standard_Boolean OpenGl_GraphicDriver::Print (const Graphic3d_CView& theCView,
293                                               const Aspect_CLayer2d& theCUnderLayer,
294                                               const Aspect_CLayer2d& theCOverLayer,
295                                               const Aspect_Handle    thePrintDC,
296                                               const Standard_Boolean theToShowBackground,
297                                               const Standard_CString theFilename,
298                                               const Aspect_PrintAlgo thePrintAlgorithm,
299                                               const Standard_Real    theScaleFactor) const
300 {
301   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
302   if (aCView == NULL
303    || !myPrintContext.IsNull())
304   {
305     return Standard_False;
306   }
307
308   Standard_Boolean isPrinted = Standard_False;
309   myPrintContext = new OpenGl_PrinterContext();
310 #ifdef _WIN32
311   isPrinted = aCView->WS->Print (myPrintContext,
312                                  theCView,
313                                  theCUnderLayer,
314                                  theCOverLayer,
315                                  thePrintDC,
316                                  theToShowBackground,
317                                  theFilename,
318                                  thePrintAlgorithm,
319                                  theScaleFactor);
320 #else
321   Standard_NotImplemented::Raise ("OpenGl_GraphicDriver::Print is implemented only on Windows");
322 #endif
323   myPrintContext.Nullify();
324   return isPrinted;
325 }
326
327 // =======================================================================
328 // function : ZBufferTriedronSetup
329 // purpose  :
330 // =======================================================================
331 void OpenGl_GraphicDriver::ZBufferTriedronSetup (const Quantity_NameOfColor theXColor,
332                                                  const Quantity_NameOfColor theYColor,
333                                                  const Quantity_NameOfColor theZColor,
334                                                  const Standard_Real        theSizeRatio,
335                                                  const Standard_Real        theAxisDiametr,
336                                                  const Standard_Integer     theNbFacettes)
337 {
338   OpenGl_Trihedron::Setup (theXColor, theYColor, theZColor, theSizeRatio, theAxisDiametr, theNbFacettes);
339 }
340
341 // =======================================================================
342 // function : TriedronDisplay
343 // purpose  :
344 // =======================================================================
345 void OpenGl_GraphicDriver::TriedronDisplay (const Graphic3d_CView&              theCView,
346                                             const Aspect_TypeOfTriedronPosition thePosition,
347                                             const Quantity_NameOfColor          theColor,
348                                             const Standard_Real                 theScale,
349                                             const Standard_Boolean              theAsWireframe)
350 {
351   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
352   if (aCView != NULL)
353   {
354     aCView->View->TriedronDisplay (aCView->WS->GetGlContext(), thePosition, theColor, theScale, theAsWireframe);
355   }
356 }
357
358 // =======================================================================
359 // function : TriedronErase
360 // purpose  :
361 // =======================================================================
362 void OpenGl_GraphicDriver::TriedronErase (const Graphic3d_CView& theCView)
363 {
364   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
365   if (aCView != NULL)
366   {
367     aCView->View->TriedronErase (aCView->WS->GetGlContext());
368   }
369 }
370
371 // =======================================================================
372 // function : TriedronEcho
373 // purpose  :
374 // =======================================================================
375 void OpenGl_GraphicDriver::TriedronEcho (const Graphic3d_CView& ,
376                                          const Aspect_TypeOfTriedronEcho )
377 {
378   // do nothing
379 }
380
381 // =======================================================================
382 // function : Environment
383 // purpose  :
384 // =======================================================================
385 void OpenGl_GraphicDriver::Environment (const Graphic3d_CView& theCView)
386 {
387   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
388   if (aCView == NULL)
389   {
390     return;
391   }
392
393   aCView->View->SetTextureEnv    (aCView->WS->GetGlContext(), theCView.Context.TextureEnv);
394   aCView->View->SetSurfaceDetail ((Visual3d_TypeOfSurfaceDetail)theCView.Context.SurfaceDetail);
395 }
396
397 // =======================================================================
398 // function : BackgroundImage
399 // purpose  :
400 // =======================================================================
401 void OpenGl_GraphicDriver::BackgroundImage (const Standard_CString  theFileName,
402                                             const Graphic3d_CView&  theCView,
403                                             const Aspect_FillMethod theFillStyle)
404 {
405   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
406   if (aCView != NULL)
407   {
408     aCView->View->CreateBackgroundTexture (theFileName, theFillStyle);
409   }
410 }
411
412 // =======================================================================
413 // function : SetBgImageStyle
414 // purpose  :
415 // =======================================================================
416 void OpenGl_GraphicDriver::SetBgImageStyle (const Graphic3d_CView&  theCView,
417                                             const Aspect_FillMethod theFillStyle)
418 {
419   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
420   if (aCView != NULL)
421   {
422     aCView->View->SetBackgroundTextureStyle (theFillStyle);
423   }
424 }
425
426 // =======================================================================
427 // function : SetBgGradientStyle
428 // purpose  :
429 // =======================================================================
430 void OpenGl_GraphicDriver::SetBgGradientStyle (const Graphic3d_CView&          theCView,
431                                                const Aspect_GradientFillMethod theFillType)
432 {
433   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
434   if (aCView != NULL)
435   {
436     aCView->View->SetBackgroundGradientType (theFillType);
437   }
438 }
439
440 // =======================================================================
441 // function : GraduatedTrihedronDisplay
442 // purpose  :
443 // =======================================================================
444 void OpenGl_GraphicDriver::GraduatedTrihedronDisplay (const Graphic3d_CView&               theCView,
445                                                       const Graphic3d_CGraduatedTrihedron& theCubic)
446 {
447   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
448   if (aCView != NULL)
449   {
450     aCView->View->GraduatedTrihedronDisplay (aCView->WS->GetGlContext(), theCubic);
451   }
452 }
453
454 // =======================================================================
455 // function : GraduatedTrihedronErase
456 // purpose  :
457 // =======================================================================
458 void OpenGl_GraphicDriver::GraduatedTrihedronErase (const Graphic3d_CView& theCView)
459 {
460   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
461   if (aCView != NULL)
462   {
463     aCView->View->GraduatedTrihedronErase (aCView->WS->GetGlContext());
464   }
465 }
466
467 // =======================================================================
468 // function : GraduatedTrihedronMinMaxValues
469 // purpose  :
470 // =======================================================================
471 void OpenGl_GraphicDriver::GraduatedTrihedronMinMaxValues (const Standard_ShortReal theMinX,
472                                                            const Standard_ShortReal theMinY,
473                                                            const Standard_ShortReal theMinZ,
474                                                            const Standard_ShortReal theMaxX,
475                                                            const Standard_ShortReal theMaxY,
476                                                            const Standard_ShortReal theMaxZ)
477 {
478   OpenGl_GraduatedTrihedron::SetMinMax (theMinX, theMinY, theMinZ, theMaxX, theMaxY, theMaxZ);
479 }