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