0024130: Implementing ray tracing visualization core
[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 // 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 #ifdef HAVE_CONFIG_H
22   #include <config.h>
23 #endif
24
25 #include <OpenGl_GraphicDriver.hxx>
26
27 #include <OpenGl_Context.hxx>
28 #include <OpenGl_GraduatedTrihedron.hxx>
29 #include <OpenGl_Group.hxx>
30 #include <OpenGl_CView.hxx>
31 #include <OpenGl_View.hxx>
32 #include <OpenGl_Text.hxx>
33 #include <OpenGl_Trihedron.hxx>
34 #include <OpenGl_Workspace.hxx>
35
36 #include <Standard_NotImplemented.hxx>
37
38 IMPLEMENT_STANDARD_HANDLE(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
39 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
40
41 namespace
42 {
43   static const Handle(OpenGl_Context) TheNullGlCtx;
44 };
45
46 // Pour eviter de "mangler" MetaGraphicDriverFactory, le nom de la
47 // fonction qui cree un Graphic3d_GraphicDriver.
48 // En effet, ce nom est recherche par la methode DlSymb de la
49 // classe OSD_SharedLibrary dans la methode SetGraphicDriver de la
50 // classe Graphic3d_GraphicDevice
51 extern "C" {
52 #if defined(_MSC_VER) // disable MS VC++ warning on C-style function returning C++ object
53   #pragma warning(push)
54   #pragma warning(disable:4190)
55 #endif
56   Standard_EXPORT Handle(Graphic3d_GraphicDriver) MetaGraphicDriverFactory (const Standard_CString theShrName)
57   {
58     Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver (theShrName);
59     return aDriver;
60   }
61 #if defined(_MSC_VER)
62   #pragma warning(pop)
63 #endif
64 }
65
66 // =======================================================================
67 // function : OpenGl_GraphicDriver
68 // purpose  :
69 // =======================================================================
70 OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Standard_CString theShrName)
71 : Graphic3d_GraphicDriver (theShrName),
72   myCaps           (new OpenGl_Caps()),
73   myMapOfView      (1, NCollection_BaseAllocator::CommonBaseAllocator()),
74   myMapOfWS        (1, NCollection_BaseAllocator::CommonBaseAllocator()),
75   myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator()),
76   myUserDrawCallback (NULL),
77   myTempText (new OpenGl_Text())
78 {
79   //
80 }
81
82 // =======================================================================
83 // function : UserDrawCallback
84 // purpose  :
85 // =======================================================================
86 OpenGl_GraphicDriver::OpenGl_UserDrawCallback_t& OpenGl_GraphicDriver::UserDrawCallback()
87 {
88   return myUserDrawCallback;
89 }
90
91 // =======================================================================
92 // function : DefaultTextHeight
93 // purpose  :
94 // =======================================================================
95 Standard_ShortReal OpenGl_GraphicDriver::DefaultTextHeight() const
96 {
97   return 16.;
98 }
99
100 // =======================================================================
101 // function : EnableVBO
102 // purpose  :
103 // =======================================================================
104 void OpenGl_GraphicDriver::EnableVBO (const Standard_Boolean theToTurnOn)
105 {
106   myCaps->vboDisable = !theToTurnOn;
107 }
108
109 // =======================================================================
110 // function : GetSharedContext
111 // purpose  :
112 // =======================================================================
113 const Handle(OpenGl_Context)& OpenGl_GraphicDriver::GetSharedContext() const
114 {
115   if (myMapOfWS.IsEmpty())
116   {
117     return TheNullGlCtx;
118   }
119
120   NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>::Iterator anIter (myMapOfWS);
121   return anIter.Value()->GetGlContext();
122 }
123
124 // =======================================================================
125 // function : MemoryInfo
126 // purpose  :
127 // =======================================================================
128 Standard_Boolean OpenGl_GraphicDriver::MemoryInfo (Standard_Size&           theFreeBytes,
129                                                    TCollection_AsciiString& theInfo) const
130 {
131   // this is extra work (for OpenGl_Context initialization)...
132   OpenGl_Context aGlCtx;
133   if (!aGlCtx.Init())
134   {
135     return Standard_False;
136   }
137   theFreeBytes = aGlCtx.AvailableMemory();
138   theInfo      = aGlCtx.MemoryInfo();
139   return !theInfo.IsEmpty();
140 }
141
142 // =======================================================================
143 // function : SetImmediateModeDrawToFront
144 // purpose  :
145 // =======================================================================
146 Standard_Boolean OpenGl_GraphicDriver::SetImmediateModeDrawToFront (const Graphic3d_CView& theCView,
147                                                                     const Standard_Boolean theDrawToFrontBuffer)
148 {
149   if (theCView.ViewId == -1)
150   {
151     return Standard_False;
152   }
153
154   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
155   if (aCView != NULL)
156   {
157     return aCView->WS->SetImmediateModeDrawToFront (theDrawToFrontBuffer);
158   }
159   return Standard_False;
160 }
161
162 // =======================================================================
163 // function : GetOpenClDeviceInfo
164 // purpose  : Returns information about device used for computations
165 // =======================================================================
166 #ifndef HAVE_OPENCL
167
168 Standard_Boolean OpenGl_GraphicDriver::GetOpenClDeviceInfo (const Graphic3d_CView&,
169   NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>&)
170 {
171   return Standard_True;
172 }
173
174 #else
175
176 Standard_Boolean OpenGl_GraphicDriver::GetOpenClDeviceInfo (const Graphic3d_CView& theCView,
177   NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theInfo)
178 {
179
180   if (theCView.ViewId == -1 || theCView.ptrView == NULL)
181   {
182     return Standard_False;
183   }
184   
185   return reinterpret_cast<const OpenGl_CView*> (theCView.ptrView)->WS->GetOpenClDeviceInfo (theInfo);
186 }
187
188 #endif
189
190 // =======================================================================
191 // function : BeginAddMode
192 // purpose  :
193 // =======================================================================
194 Standard_Boolean OpenGl_GraphicDriver::BeginAddMode (const Graphic3d_CView& theCView)
195 {
196   if (theCView.ViewId == -1)
197   {
198     return Standard_False;
199   }
200
201   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
202   if (aCView != NULL && aCView->WS->BeginAddMode())
203   {
204     myImmediateWS = aCView->WS;
205     return Standard_True;
206   }
207
208   return Standard_False;
209 }
210
211 // =======================================================================
212 // function : EndAddMode
213 // purpose  :
214 // =======================================================================
215 void OpenGl_GraphicDriver::EndAddMode()
216 {
217   if (!myImmediateWS.IsNull())
218   {
219     myImmediateWS->EndAddMode();
220     myImmediateWS.Nullify();
221   }
222 }
223
224 // =======================================================================
225 // function : BeginImmediatMode
226 // purpose  :
227 // =======================================================================
228 Standard_Boolean OpenGl_GraphicDriver::BeginImmediatMode (const Graphic3d_CView& theCView,
229                                                           const Aspect_CLayer2d& /*theCUnderLayer*/,
230                                                           const Aspect_CLayer2d& /*theCOverLayer*/,
231                                                           const Standard_Boolean theDoubleBuffer,
232                                                           const Standard_Boolean theRetainMode)
233 {
234   if (theCView.ViewId == -1)
235   {
236     return Standard_False;
237   }
238
239   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
240   if (aCView != NULL && aCView->WS->BeginImmediatMode (theCView, theDoubleBuffer, theRetainMode))
241   {
242     myImmediateWS = aCView->WS;
243     return Standard_True;
244   }
245
246   return Standard_False;
247 }
248
249 // =======================================================================
250 // function : ClearImmediatMode
251 // purpose  :
252 // =======================================================================
253 void OpenGl_GraphicDriver::ClearImmediatMode (const Graphic3d_CView& theCView,
254                                               const Standard_Boolean theToFlush)
255 {
256   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
257   if (aCView != NULL)
258   {
259     aCView->WS->ClearImmediatMode (theCView, theToFlush);
260   }
261 }
262
263 // =======================================================================
264 // function : DrawStructure
265 // purpose  :
266 // =======================================================================
267 void OpenGl_GraphicDriver::DrawStructure (const Graphic3d_CStructure& theCStructure)
268 {
269   OpenGl_Structure* aStructure = (OpenGl_Structure* )theCStructure.ptrStructure;
270   if (aStructure == NULL)
271   {
272     return;
273   }
274
275   if (!myImmediateWS.IsNull())
276   {
277     myImmediateWS->DrawStructure (aStructure);
278   }
279 }
280
281 // =======================================================================
282 // function : EndImmediatMode
283 // purpose  :
284 // =======================================================================
285 void OpenGl_GraphicDriver::EndImmediatMode (const Standard_Integer )
286 {
287   if (!myImmediateWS.IsNull())
288   {
289     myImmediateWS->EndImmediatMode();
290     myImmediateWS.Nullify();
291   }
292 }
293
294 // =======================================================================
295 // function : Print
296 // purpose  :
297 // =======================================================================
298 Standard_Boolean OpenGl_GraphicDriver::Print (const Graphic3d_CView& theCView,
299                                               const Aspect_CLayer2d& theCUnderLayer,
300                                               const Aspect_CLayer2d& theCOverLayer,
301                                               const Aspect_Handle    thePrintDC,
302                                               const Standard_Boolean theToShowBackground,
303                                               const Standard_CString theFilename,
304                                               const Aspect_PrintAlgo thePrintAlgorithm,
305                                               const Standard_Real    theScaleFactor) const
306 {
307   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
308   if (aCView == NULL
309    || !myPrintContext.IsNull())
310   {
311     return Standard_False;
312   }
313
314   Standard_Boolean isPrinted = Standard_False;
315   myPrintContext = new OpenGl_PrinterContext();
316 #ifdef _WIN32
317   isPrinted = aCView->WS->Print (myPrintContext,
318                                  theCView,
319                                  theCUnderLayer,
320                                  theCOverLayer,
321                                  thePrintDC,
322                                  theToShowBackground,
323                                  theFilename,
324                                  thePrintAlgorithm,
325                                  theScaleFactor);
326 #else
327   Standard_NotImplemented::Raise ("OpenGl_GraphicDriver::Print is implemented only on Windows");
328 #endif
329   myPrintContext.Nullify();
330   return isPrinted;
331 }
332
333 // =======================================================================
334 // function : Text
335 // purpose  :
336 // =======================================================================
337 void OpenGl_GraphicDriver::Text (const Graphic3d_CGroup&                 theCGroup,
338                                  const TCollection_ExtendedString&       theText,
339                                  const Graphic3d_Vertex&                 thePoint,
340                                  const Standard_Real                     theHeight,
341                                  const Quantity_PlaneAngle               /*theAngle*/,
342                                  const Graphic3d_TextPath                /*theTp*/,
343                                  const Graphic3d_HorizontalTextAlignment theHta,
344                                  const Graphic3d_VerticalTextAlignment   theVta,
345                                  const Standard_Boolean                  /*theToEvalMinMax*/)
346 {
347   if (theCGroup.ptrGroup == NULL)
348   {
349     return;
350   }
351
352   OpenGl_TextParam aParams;
353   aParams.Height = int ((theHeight < 2.0) ? DefaultTextHeight() : theHeight);
354   aParams.HAlign = theHta;
355   aParams.VAlign = theVta;
356   const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z());
357   OpenGl_Text* aText = new OpenGl_Text (theText, aPoint, aParams);
358   ((OpenGl_Group* )theCGroup.ptrGroup)->AddElement (TelText, aText);
359 }
360
361 // =======================================================================
362 // function : Text
363 // purpose  : Wrapper CString -> TCollection_ExtendedString
364 // =======================================================================
365 void OpenGl_GraphicDriver::Text (const Graphic3d_CGroup&                 theCGroup,
366                                  const Standard_CString                  theText,
367                                  const Graphic3d_Vertex&                 thePoint,
368                                  const Standard_Real                     theHeight,
369                                  const Quantity_PlaneAngle               theAngle,
370                                  const Graphic3d_TextPath                theTp,
371                                  const Graphic3d_HorizontalTextAlignment theHta,
372                                  const Graphic3d_VerticalTextAlignment   theVta,
373                                  const Standard_Boolean                  theToEvalMinMax)
374 {
375   OpenGl_GraphicDriver::Text (theCGroup, TCollection_ExtendedString (theText),
376                               thePoint, theHeight, theAngle, theTp, theHta, theVta, theToEvalMinMax);
377 }
378
379 // =======================================================================
380 // function : Text
381 // purpose  : Wrapper CString -> TCollection_ExtendedString
382 // =======================================================================
383 void OpenGl_GraphicDriver::Text (const Graphic3d_CGroup& theCGroup,
384                                  const Standard_CString  theText,
385                                  const Graphic3d_Vertex& thePoint,
386                                  const Standard_Real     theHeight,
387                                  const Standard_Boolean  theToEvalMinMax)
388 {
389   OpenGl_GraphicDriver::Text (theCGroup, TCollection_ExtendedString (theText), thePoint, theHeight, theToEvalMinMax);
390 }
391
392 // =======================================================================
393 // function : Text
394 // purpose  : Wrapper with default values
395 // =======================================================================
396 void OpenGl_GraphicDriver::Text (const Graphic3d_CGroup&           theCGroup,
397                                  const TCollection_ExtendedString& theText,
398                                  const Graphic3d_Vertex&           thePoint,
399                                  const Standard_Real               theHeight,
400                                  const Standard_Boolean            theToEvalMinMax)
401 {
402   OpenGl_GraphicDriver::Text (theCGroup,
403                               theText, thePoint, theHeight, 0.0,
404                               Graphic3d_TP_RIGHT, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM,
405                               theToEvalMinMax);
406 }
407
408 // =======================================================================
409 // function : ZBufferTriedronSetup
410 // purpose  :
411 // =======================================================================
412 void OpenGl_GraphicDriver::ZBufferTriedronSetup (const Quantity_NameOfColor theXColor,
413                                                  const Quantity_NameOfColor theYColor,
414                                                  const Quantity_NameOfColor theZColor,
415                                                  const Standard_Real        theSizeRatio,
416                                                  const Standard_Real        theAxisDiametr,
417                                                  const Standard_Integer     theNbFacettes)
418 {
419   OpenGl_Trihedron::Setup (theXColor, theYColor, theZColor, theSizeRatio, theAxisDiametr, theNbFacettes);
420 }
421
422 // =======================================================================
423 // function : TriedronDisplay
424 // purpose  :
425 // =======================================================================
426 void OpenGl_GraphicDriver::TriedronDisplay (const Graphic3d_CView&              theCView,
427                                             const Aspect_TypeOfTriedronPosition thePosition,
428                                             const Quantity_NameOfColor          theColor,
429                                             const Standard_Real                 theScale,
430                                             const Standard_Boolean              theAsWireframe)
431 {
432   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
433   if (aCView != NULL)
434   {
435     aCView->View->TriedronDisplay (aCView->WS->GetGlContext(), thePosition, theColor, theScale, theAsWireframe);
436   }
437 }
438
439 // =======================================================================
440 // function : TriedronErase
441 // purpose  :
442 // =======================================================================
443 void OpenGl_GraphicDriver::TriedronErase (const Graphic3d_CView& theCView)
444 {
445   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
446   if (aCView != NULL)
447   {
448     aCView->View->TriedronErase (aCView->WS->GetGlContext());
449   }
450 }
451
452 // =======================================================================
453 // function : TriedronEcho
454 // purpose  :
455 // =======================================================================
456 void OpenGl_GraphicDriver::TriedronEcho (const Graphic3d_CView& ,
457                                          const Aspect_TypeOfTriedronEcho )
458 {
459   // do nothing
460 }
461
462 // =======================================================================
463 // function : Environment
464 // purpose  :
465 // =======================================================================
466 void OpenGl_GraphicDriver::Environment (const Graphic3d_CView& theCView)
467 {
468   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
469   if (aCView == NULL)
470   {
471     return;
472   }
473
474   aCView->View->SetTextureEnv    (aCView->WS->GetGlContext(), theCView.Context.TextureEnv);
475   aCView->View->SetSurfaceDetail ((Visual3d_TypeOfSurfaceDetail)theCView.Context.SurfaceDetail);
476 }
477
478 // =======================================================================
479 // function : BackgroundImage
480 // purpose  :
481 // =======================================================================
482 void OpenGl_GraphicDriver::BackgroundImage (const Standard_CString  theFileName,
483                                             const Graphic3d_CView&  theCView,
484                                             const Aspect_FillMethod theFillStyle)
485 {
486   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
487   if (aCView != NULL)
488   {
489     aCView->View->CreateBackgroundTexture (theFileName, theFillStyle);
490   }
491 }
492
493 // =======================================================================
494 // function : SetBgImageStyle
495 // purpose  :
496 // =======================================================================
497 void OpenGl_GraphicDriver::SetBgImageStyle (const Graphic3d_CView&  theCView,
498                                             const Aspect_FillMethod theFillStyle)
499 {
500   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
501   if (aCView != NULL)
502   {
503     aCView->View->SetBackgroundTextureStyle (theFillStyle);
504   }
505 }
506
507 // =======================================================================
508 // function : SetBgGradientStyle
509 // purpose  :
510 // =======================================================================
511 void OpenGl_GraphicDriver::SetBgGradientStyle (const Graphic3d_CView&          theCView,
512                                                const Aspect_GradientFillMethod theFillType)
513 {
514   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
515   if (aCView != NULL)
516   {
517     aCView->View->SetBackgroundGradientType (theFillType);
518   }
519 }
520
521 // =======================================================================
522 // function : GraduatedTrihedronDisplay
523 // purpose  :
524 // =======================================================================
525 void OpenGl_GraphicDriver::GraduatedTrihedronDisplay (const Graphic3d_CView&               theCView,
526                                                       const Graphic3d_CGraduatedTrihedron& theCubic)
527 {
528   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
529   if (aCView != NULL)
530   {
531     aCView->View->GraduatedTrihedronDisplay (aCView->WS->GetGlContext(), theCubic);
532   }
533 }
534
535 // =======================================================================
536 // function : GraduatedTrihedronErase
537 // purpose  :
538 // =======================================================================
539 void OpenGl_GraphicDriver::GraduatedTrihedronErase (const Graphic3d_CView& theCView)
540 {
541   const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
542   if (aCView != NULL)
543   {
544     aCView->View->GraduatedTrihedronErase (aCView->WS->GetGlContext());
545   }
546 }
547
548 // =======================================================================
549 // function : GraduatedTrihedronMinMaxValues
550 // purpose  :
551 // =======================================================================
552 void OpenGl_GraphicDriver::GraduatedTrihedronMinMaxValues (const Standard_ShortReal theMinX,
553                                                            const Standard_ShortReal theMinY,
554                                                            const Standard_ShortReal theMinZ,
555                                                            const Standard_ShortReal theMaxX,
556                                                            const Standard_ShortReal theMaxY,
557                                                            const Standard_ShortReal theMaxZ)
558 {
559   OpenGl_GraduatedTrihedron::SetMinMax (theMinX, theMinY, theMinZ, theMaxX, theMaxY, theMaxZ);
560 }