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