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