0026128: Visualization, TKOpenGl - fix misprint in external GLX context initialization
[occt.git] / src / OpenGl / OpenGl_Trihedron.cxx
1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <OpenGl_Trihedron.hxx>
17
18 #include <OpenGl_GlCore11.hxx>
19
20 #include <Graphic3d_ArrayOfSegments.hxx>
21 #include <Graphic3d_ArrayOfPolylines.hxx>
22 #include <OpenGl_View.hxx>
23 #include <OpenGl_Workspace.hxx>
24 #include <Precision.hxx>
25
26 namespace
27 {
28   static const OpenGl_TextParam THE_LABEL_PARAMS =
29   {
30     16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
31   };
32 }
33
34 // =======================================================================
35 // function : resetTransformations
36 // purpose  :
37 // =======================================================================
38 void OpenGl_Trihedron::resetTransformations (const Handle(OpenGl_Workspace)& theWorkspace) const
39 {
40   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
41   const Handle(OpenGl_View)& aView    = theWorkspace->ActiveView();
42   GLdouble anU = 1.0;
43   GLdouble aV = 1.0;
44   if (aView->Height() < aView->Width())
45   {
46     aV = aView->Width() / aView->Height();
47   }
48   else
49   {
50     anU = aView->Height() / aView->Width();
51   }
52
53   // Reading the transformation matrices and projection of sight
54   // to cancel translations (last columns of matrices).
55   OpenGl_Mat4d aModelMatrix;
56   OpenGl_Mat4d aProjMatrix;
57   aModelMatrix.Convert (aContext->WorldViewState.Current());
58
59   // Cancel the translation that can be assigned to the view
60   aModelMatrix.ChangeValue (0, 3) = 0.0;
61   aModelMatrix.ChangeValue (1, 3) = 0.0;
62   aModelMatrix.ChangeValue (2, 3) = 0.0;
63
64   aProjMatrix.ChangeValue (0, 0) = 2.0 / anU;
65   aProjMatrix.ChangeValue (1, 0) = 0.0;
66   aProjMatrix.ChangeValue (2, 0) = 0.0;
67   aProjMatrix.ChangeValue (3, 0) = 0.0;
68
69   aProjMatrix.ChangeValue (0, 1) = 0.0;
70   aProjMatrix.ChangeValue (1, 1) = 2.0 / aV;
71   aProjMatrix.ChangeValue (2, 1) = 0.0;
72   aProjMatrix.ChangeValue (3, 1) = 0.0;
73
74   aProjMatrix.ChangeValue (0, 2) = 0.0;
75   aProjMatrix.ChangeValue (1, 2) = 0.0;
76   aProjMatrix.ChangeValue (2, 2) = -2.0 * 0.01;
77   aProjMatrix.ChangeValue (3, 2) = 0.0;
78
79   aProjMatrix.ChangeValue (0, 3) = 0.0;
80   aProjMatrix.ChangeValue (1, 3) = 0.0;
81   aProjMatrix.ChangeValue (2, 3) = 0.0;
82   aProjMatrix.ChangeValue (3, 3) = 1.0;
83
84   // Define trihedron position in the view
85   switch (myPos)
86   {
87     case Aspect_TOTP_LEFT_LOWER:
88     {
89       OpenGl_Utils::Translate (aProjMatrix,
90         -0.5 * anU + myScale, -0.5 * aV + myScale, 0.0);
91       break;
92     }
93     case Aspect_TOTP_LEFT_UPPER:
94     {
95       OpenGl_Utils::Translate (aProjMatrix,
96         -0.5 * anU + myScale, 0.5 * aV - myScale - myScale / 3.0, 0.0);
97       break;
98     }
99     case Aspect_TOTP_RIGHT_LOWER:
100     {
101       OpenGl_Utils::Translate (aProjMatrix,
102         0.5 * anU - myScale - myScale / 3.0, -0.5 * aV + myScale, 0.0);
103       break;
104     }
105     case Aspect_TOTP_RIGHT_UPPER:
106     {
107       OpenGl_Utils::Translate (aProjMatrix,
108         0.5 * anU - myScale - myScale / 3.0, 0.5 * aV - myScale - myScale / 3.0, 0.0);
109       break;
110     }
111     //case Aspect_TOTP_CENTER:
112     default:
113       break;
114   }
115
116   aContext->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
117   aContext->ApplyProjectionMatrix();
118
119   aContext->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
120   aContext->ApplyWorldViewMatrix();
121 }
122
123 // =======================================================================
124 // function : redraw
125 // purpose  :
126 // =======================================================================
127 void OpenGl_Trihedron::redraw (const Handle(OpenGl_Workspace)& theWorkspace) const
128 {
129   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
130   aContext->WorldViewState.Push();
131   aContext->ProjectionState.Push();
132
133   resetTransformations (theWorkspace);
134
135   // Set trihedron size parameters
136   GLdouble aScale = myScale;
137   aScale *= myRatio;
138   const Standard_Real aLineRatio = 0.75;
139   const GLdouble aLineLength = aScale * aLineRatio;
140   const GLdouble aConeDiametr     = aScale * myDiameter;
141   const GLdouble aConeLength      = aScale * (1.0 - aLineRatio);
142   const GLdouble aRayon = aScale / 30.0;
143
144   // Create primitive line here for changing length
145   if (!myLine.IsInitialized())
146   {
147     Handle(Graphic3d_ArrayOfSegments) aGraphicArray = new Graphic3d_ArrayOfSegments (2);
148     aGraphicArray->AddVertex (0.0, 0.0, 0.0);
149     aGraphicArray->AddVertex (0.0, 0.0, aLineLength);
150     myLine.InitBuffers (aContext, Graphic3d_TOPA_SEGMENTS, aGraphicArray->Indices(),
151                         aGraphicArray->Attributes(),
152                         aGraphicArray->Bounds());
153   }
154
155   if (!myCircle.IsInitialized())
156   {
157     const Standard_Integer THE_CIRCLE_SERMENTS_NB = 24;
158     Handle(Graphic3d_ArrayOfPolylines) anCircleArray = new Graphic3d_ArrayOfPolylines (THE_CIRCLE_SERMENTS_NB + 2);
159
160     const Standard_Real THE_CIRCLE_SEGMENT_ANGLE = 2.0 * M_PI / THE_CIRCLE_SERMENTS_NB;
161     for (Standard_Integer anIt = THE_CIRCLE_SERMENTS_NB; anIt >= 0; --anIt)
162     {
163       anCircleArray->AddVertex (aRayon * sin (anIt * THE_CIRCLE_SEGMENT_ANGLE),
164                                 aRayon * cos (anIt * THE_CIRCLE_SEGMENT_ANGLE), 0.0);
165     }
166     anCircleArray->AddVertex (aRayon * sin (THE_CIRCLE_SERMENTS_NB * THE_CIRCLE_SEGMENT_ANGLE),
167                               aRayon * cos (THE_CIRCLE_SERMENTS_NB * THE_CIRCLE_SEGMENT_ANGLE), 0.0);
168
169     myCircle.InitBuffers (aContext, Graphic3d_TOPA_POLYLINES, anCircleArray->Indices(),
170                           anCircleArray->Attributes(), anCircleArray->Bounds());
171   }
172
173   if (!myDisk.IsInitialized())
174   {
175     myDisk.Init (0.0, static_cast<GLfloat> (aConeDiametr), myNbFacettes, 1);
176   }
177
178   if (!myCone.IsInitialized())
179   {
180     myCone.Init (static_cast<GLfloat> (aConeDiametr), 0.0f, static_cast<GLfloat> (aConeLength), myNbFacettes, 1);
181   }
182
183   OpenGl_AspectFace anAspectX;
184   OpenGl_AspectFace anAspectY;
185   OpenGl_AspectFace anAspectZ;
186   OpenGl_AspectLine anAspectLine;
187   memcpy (anAspectX.ChangeIntFront().matcol.rgb, myXColor.GetData(), sizeof (TEL_COLOUR));
188   memcpy (anAspectY.ChangeIntFront().matcol.rgb, myYColor.GetData(), sizeof (TEL_COLOUR));
189   memcpy (anAspectZ.ChangeIntFront().matcol.rgb, myZColor.GetData(), sizeof (TEL_COLOUR));
190   OpenGl_Mat4d aModelMatrix;
191   aModelMatrix.Convert (aContext->WorldViewState.Current());
192   OpenGl_Mat4d aModelViewX (aModelMatrix);
193   OpenGl_Mat4d aModelViewY (aModelMatrix);
194   OpenGl_Mat4d aModelViewZ (aModelMatrix);
195
196   // Set line aspect
197   const OpenGl_AspectLine* aCurrentAspectLine = theWorkspace->AspectLine (Standard_True);
198   CALL_DEF_CONTEXTLINE aLineAspect = {1, 1, { 1.F, 1.F, 1.F },  aCurrentAspectLine->Type(), aCurrentAspectLine->Width()};
199   aLineAspect.Color.r = myZColor.r();
200   aLineAspect.Color.g = myZColor.g();
201   aLineAspect.Color.b = myZColor.b();
202   anAspectLine.SetAspect (aLineAspect);
203
204   // Disable depth test and face culling
205   GLboolean wasDepthMaskEnabled = GL_FALSE;
206   GLint aDepthFuncBack = 0, aCullFaceModeBack = GL_BACK;
207   const GLboolean wasDepthEnabled    = aContext->core11fwd->glIsEnabled (GL_DEPTH_TEST);
208   const GLboolean wasCullFaceEnabled = aContext->core11fwd->glIsEnabled (GL_CULL_FACE);
209   aContext->core11fwd->glGetIntegerv (GL_DEPTH_FUNC,      &aDepthFuncBack);
210   aContext->core11fwd->glGetIntegerv (GL_CULL_FACE_MODE,  &aCullFaceModeBack);
211   aContext->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &wasDepthMaskEnabled);
212   if (!wasDepthEnabled)
213   {
214     aContext->core11fwd->glEnable (GL_DEPTH_TEST);
215     aContext->core11fwd->glClear (GL_DEPTH_BUFFER_BIT);
216   }
217   if (!wasDepthMaskEnabled)
218   {
219     aContext->core11fwd->glDepthMask (GL_TRUE);
220   }
221   aContext->core11fwd->glCullFace (GL_BACK);
222   if (!wasCullFaceEnabled)
223   {
224     aContext->core11fwd->glEnable (GL_CULL_FACE);
225   }
226
227   // Origin
228   myCircle.Render (theWorkspace);
229
230   // Z axis
231   const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace(&anAspectZ);
232   theWorkspace->SetAspectLine (&anAspectLine);
233   myLine.Render (theWorkspace);
234   OpenGl_Utils::Translate (aModelViewZ, 0.0, 0.0, aLineLength);
235   aContext->WorldViewState.SetCurrent<Standard_Real>(aModelViewZ);
236   aContext->ApplyWorldViewMatrix();
237   myDisk.Render (theWorkspace);
238   myCone.Render (theWorkspace);
239
240   // X axis
241   theWorkspace->SetAspectFace (&anAspectX);
242   OpenGl_Utils::Rotate (aModelViewX, 90.0, 0.0, aScale, 0.0);
243   aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewX);
244   aContext->ApplyWorldViewMatrix();
245
246   aLineAspect.Color.r = myXColor.r();
247   aLineAspect.Color.g = myXColor.g();
248   aLineAspect.Color.b = myXColor.b();
249   anAspectLine.SetAspect (aLineAspect);
250   theWorkspace->SetAspectLine (&anAspectLine);
251   myLine.Render (theWorkspace);
252   OpenGl_Utils::Translate (aModelViewX, 0.0, 0.0, aLineLength);
253   aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewX);
254   aContext->ApplyWorldViewMatrix();
255   myDisk.Render (theWorkspace);
256   myCone.Render (theWorkspace);
257
258   // Y axis
259   theWorkspace->SetAspectFace (&anAspectY);
260   OpenGl_Utils::Rotate (aModelViewY, -90.0, aScale, 0.0, 0.0);
261   aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewY);
262   aContext->ApplyWorldViewMatrix();
263
264   aLineAspect.Color.r = myYColor.r();
265   aLineAspect.Color.g = myYColor.g();
266   aLineAspect.Color.b = myYColor.b();
267   anAspectLine.SetAspect (aLineAspect);
268   theWorkspace->SetAspectLine (&anAspectLine);
269   myLine.Render (theWorkspace);
270   OpenGl_Utils::Translate (aModelViewY, 0.0, 0.0, aLineLength);
271   aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewY);
272   aContext->ApplyWorldViewMatrix();
273   myDisk.Render (theWorkspace);
274   myCone.Render (theWorkspace);
275
276   // Restore aspects
277   theWorkspace->SetAspectFace (anOldAspectFace);
278
279   if (!wasDepthEnabled)
280   {
281     aContext->core11fwd->glDisable (GL_DEPTH_TEST);
282   }
283   if (!wasDepthMaskEnabled)
284   {
285     aContext->core11fwd->glDepthMask (GL_FALSE);
286   }
287   if (!wasCullFaceEnabled)
288   {
289     aContext->core11fwd->glDisable (GL_CULL_FACE);
290   }
291   aContext->core11fwd->glCullFace (aCullFaceModeBack);
292
293   // Always write the text
294   aContext->core11fwd->glDepthFunc (GL_ALWAYS);
295
296   // Render labels
297   myLabelX.SetPosition (OpenGl_Vec3 (float (aScale + 2.0 * aRayon), 0.0f, float (-aRayon)));
298   myLabelY.SetPosition (OpenGl_Vec3 (float (aRayon), float (aScale + 3.0 * aRayon), float (2.0 * aRayon)));
299   myLabelZ.SetPosition (OpenGl_Vec3 (float (-2.0 * aRayon), float (0.5 * aRayon), float (aScale + 3.0 * aRayon)));
300   aContext->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
301   aContext->ApplyWorldViewMatrix();
302   myLabelX.Render (theWorkspace);
303   myLabelY.Render (theWorkspace);
304   myLabelZ.Render (theWorkspace);
305
306   aContext->core11fwd->glDepthFunc (aDepthFuncBack);
307   aContext->WorldViewState.Pop();
308   aContext->ProjectionState.Pop();
309   aContext->ApplyProjectionMatrix();
310 }
311
312 // =======================================================================
313 // function : redrawZBuffer
314 // purpose  :
315 // =======================================================================
316 void OpenGl_Trihedron::redrawZBuffer (const Handle(OpenGl_Workspace)& theWorkspace) const
317 {
318   Handle(OpenGl_Context) aContext = theWorkspace->GetGlContext();
319   aContext->WorldViewState.Push();
320   aContext->ProjectionState.Push();
321
322   resetTransformations (theWorkspace);
323
324   const GLdouble aScale = myScale * myRatio;
325
326   const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
327   const TEL_COLOUR&        aLineColor   = anAspectLine->Color();
328
329   // Create the trihedron
330   const Standard_Real THE_CYLINDER_LENGTH = 0.75;
331   const GLdouble aCylinderLength  = aScale * THE_CYLINDER_LENGTH;
332   const GLdouble aCylinderDiametr = aScale * myDiameter;
333   const GLdouble aConeDiametr     = aCylinderDiametr * 2.0;
334   const GLdouble aConeLength      = aScale * (1.0 - THE_CYLINDER_LENGTH);
335
336   // Position des Axes
337   GLdouble aTriedronAxeX[3] = { aScale, 0.0,    0.0 };
338   GLdouble aTriedronAxeY[3] = { 0.0,    aScale, 0.0 };
339   if (!myDisk.IsInitialized())
340   {
341     myDisk.Init (static_cast<GLfloat> (aCylinderDiametr),
342                  static_cast<GLfloat> (aConeDiametr),
343                  myNbFacettes, 1);
344   }
345
346   if (!mySphere.IsInitialized())
347   {
348     mySphere.Init (static_cast<GLfloat> (aCylinderDiametr * 2.0), myNbFacettes, myNbFacettes);
349   }
350
351   if (!myCone.IsInitialized())
352   {
353     myCone.Init (static_cast<GLfloat> (aConeDiametr), 0.0f, static_cast<GLfloat> (aConeLength), myNbFacettes, 1);
354   }
355
356   if (!myCylinder.IsInitialized())
357   {
358     myCylinder.Init (static_cast<GLfloat> (aCylinderDiametr),
359                      static_cast<GLfloat> (aCylinderDiametr),
360                      static_cast<GLfloat> (aCylinderLength),
361                      myNbFacettes, 1);
362   }
363
364   GLboolean wasDepthMaskEnabled = GL_FALSE;
365   GLint aDepthFuncBack = 0, aCullFaceModeBack = GL_BACK;
366   const GLboolean wasDepthEnabled    = aContext->core11fwd->glIsEnabled (GL_DEPTH_TEST);
367   const GLboolean wasCullFaceEnabled = aContext->core11fwd->glIsEnabled (GL_CULL_FACE);
368   aContext->core11fwd->glGetIntegerv (GL_DEPTH_FUNC,      &aDepthFuncBack);
369   aContext->core11fwd->glGetIntegerv (GL_CULL_FACE_MODE,  &aCullFaceModeBack);
370   aContext->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &wasDepthMaskEnabled);
371   if (!wasDepthEnabled)
372   {
373     aContext->core11fwd->glEnable (GL_DEPTH_TEST);
374     aContext->core11fwd->glClear (GL_DEPTH_BUFFER_BIT);
375   }
376   if (!wasDepthMaskEnabled)
377   {
378     aContext->core11fwd->glDepthMask (GL_TRUE);
379   }
380   aContext->core11fwd->glCullFace (GL_BACK);
381   if (!wasCullFaceEnabled)
382   {
383     aContext->core11fwd->glEnable (GL_CULL_FACE);
384   }
385
386   OpenGl_AspectFace anAspectC;
387   OpenGl_AspectFace anAspectX;
388   OpenGl_AspectFace anAspectY;
389   OpenGl_AspectFace anAspectZ;
390   memcpy (anAspectX.ChangeIntFront().matcol.rgb, myXColor.GetData(), sizeof (TEL_COLOUR));
391   memcpy (anAspectY.ChangeIntFront().matcol.rgb, myYColor.GetData(), sizeof (TEL_COLOUR));
392   memcpy (anAspectZ.ChangeIntFront().matcol.rgb, myZColor.GetData(), sizeof (TEL_COLOUR));
393   memcpy (anAspectC.ChangeIntFront().matcol.rgb, aLineColor.rgb,     sizeof (TEL_COLOUR));
394
395   OpenGl_Mat4d aModelMatrix;
396   aModelMatrix.Convert (aContext->WorldViewState.Current());
397   for (Standard_Integer aPass = 0; aPass < 2; ++aPass)
398   {
399     OpenGl_Mat4d aModelViewX (aModelMatrix);
400     OpenGl_Mat4d aModelViewY (aModelMatrix);
401     OpenGl_Mat4d aModelViewZ (aModelMatrix);
402     aContext->core11fwd->glDepthFunc (aPass == 0 ? GL_ALWAYS : GL_LEQUAL);
403
404     const OpenGl_AspectFace* anOldAspect = theWorkspace->SetAspectFace (&anAspectC);
405
406     // Origin
407     aContext->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
408     aContext->ApplyWorldViewMatrix();
409     mySphere.Render (theWorkspace);
410
411     // Z axis
412     theWorkspace->SetAspectFace (&anAspectZ);
413     myCylinder.Render (theWorkspace);
414     OpenGl_Utils::Translate (aModelViewZ, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH);
415     aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewZ);
416     aContext->ApplyWorldViewMatrix();
417     myDisk.Render (theWorkspace);
418     myCone.Render (theWorkspace);
419
420     // X axis
421     theWorkspace->SetAspectFace (&anAspectX);
422     OpenGl_Utils::Rotate (aModelViewX, 90.0, aTriedronAxeY[0], aTriedronAxeY[1], aTriedronAxeY[2]);
423     aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewX);
424     aContext->ApplyWorldViewMatrix();
425     myCylinder.Render (theWorkspace);
426     OpenGl_Utils::Translate (aModelViewX, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH);
427     aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewX);
428     aContext->ApplyWorldViewMatrix();
429     myDisk.Render (theWorkspace);
430     myCone.Render (theWorkspace);
431
432     // Y axis
433     theWorkspace->SetAspectFace (&anAspectY);
434     OpenGl_Utils::Rotate (aModelViewY, -90.0, aTriedronAxeX[0], aTriedronAxeX[1], aTriedronAxeX[2]);
435     aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewY);
436     aContext->ApplyWorldViewMatrix();
437     myCylinder.Render (theWorkspace);
438     OpenGl_Utils::Translate (aModelViewY, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH);
439     aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewY);
440     aContext->ApplyWorldViewMatrix();
441     myDisk.Render (theWorkspace);
442     myCone.Render (theWorkspace);
443
444     theWorkspace->SetAspectFace (anOldAspect);
445   }
446
447   if (!wasDepthEnabled)
448   {
449     aContext->core11fwd->glDisable (GL_DEPTH_TEST);
450   }
451   if (!wasDepthMaskEnabled)
452   {
453     aContext->core11fwd->glDepthMask (GL_FALSE);
454   }
455   if (!wasCullFaceEnabled)
456   {
457     aContext->core11fwd->glDisable (GL_CULL_FACE);
458   }
459   aContext->core11fwd->glCullFace (aCullFaceModeBack);
460
461   // Always write the text
462   aContext->core11fwd->glDepthFunc (GL_ALWAYS);
463
464   // draw axes labels
465   const GLdouble rayon = aScale / 30.0;
466   myLabelX.SetPosition (OpenGl_Vec3(float(aScale + 2.0 * rayon), 0.0f,                        float(-rayon)));
467   myLabelY.SetPosition (OpenGl_Vec3(float(rayon),                float(aScale + 3.0 * rayon), float(2.0 * rayon)));
468   myLabelZ.SetPosition (OpenGl_Vec3(float(-2.0 * rayon),         float(0.5 * rayon),          float(aScale + 3.0 * rayon)));
469   aContext->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
470   aContext->ApplyWorldViewMatrix();
471   myLabelX.Render (theWorkspace);
472   myLabelY.Render (theWorkspace);
473   myLabelZ.Render (theWorkspace);
474
475   aContext->core11fwd->glDepthFunc (aDepthFuncBack);
476
477   aContext->WorldViewState.Pop();
478   aContext->ProjectionState.Pop();
479   aContext->ApplyProjectionMatrix();
480 }
481
482 // =======================================================================
483 // function : OpenGl_Trihedron
484 // purpose  :
485 // =======================================================================
486 OpenGl_Trihedron::OpenGl_Trihedron()
487 : myPos (Aspect_TOTP_LEFT_LOWER),
488   myScale (1.0),
489   myIsWireframe (Standard_False),
490   myXColor (1.0f, 0.0f, 0.0f, 0.6f),
491   myYColor (0.0f, 1.0f, 0.0f, 0.6f),
492   myZColor (0.0f, 0.0f, 1.0f, 0.6f),
493   myRatio      (0.8f),
494   myDiameter   (0.05f),
495   myNbFacettes (12),
496   myLabelX ("X", OpenGl_Vec3(1.0f, 0.0f, 0.0f), THE_LABEL_PARAMS),
497   myLabelY ("Y", OpenGl_Vec3(0.0f, 1.0f, 0.0f), THE_LABEL_PARAMS),
498   myLabelZ ("Z", OpenGl_Vec3(0.0f, 0.0f, 1.0f), THE_LABEL_PARAMS),
499   myLine   (NULL), // do not register arrays UID - trihedron is not intended to be drawn by Ray Tracing engine
500   myCircle (NULL)
501 {
502   const TEL_COLOUR aWhiteColor = {{ 1.0f, 1.0f, 1.0f, 1.0f }};
503   myAspectLine.ChangeColor()    = aWhiteColor;
504   myAspectText.ChangeColor()    = aWhiteColor;
505   myAspectText.ChangeFontName() = "Courier";
506 }
507
508 // =======================================================================
509 // function : ~OpenGl_Trihedron
510 // purpose  :
511 // =======================================================================
512 OpenGl_Trihedron::~OpenGl_Trihedron()
513 {
514   //
515 }
516
517 // =======================================================================
518 // function : Release
519 // purpose  :
520 // =======================================================================
521 void OpenGl_Trihedron::Release (OpenGl_Context* theCtx)
522 {
523   myLabelX.Release (theCtx);
524   myLabelY.Release (theCtx);
525   myLabelZ.Release (theCtx);
526   myAspectLine.Release (theCtx);
527   myAspectText.Release (theCtx);
528   myCone    .Release (theCtx);
529   myDisk    .Release (theCtx);
530   mySphere  .Release (theCtx);
531   myCylinder.Release (theCtx);
532   myLine.Release (theCtx);
533   myCircle.Release (theCtx);
534 }
535
536 // =======================================================================
537 // function : invalidate
538 // purpose  :
539 // =======================================================================
540 void OpenGl_Trihedron::invalidate()
541 {
542   myCone    .Invalidate();
543   myDisk    .Invalidate();
544   mySphere  .Invalidate();
545   myCylinder.Invalidate();
546   myLine    .Invalidate();
547   myCircle  .Invalidate();
548 }
549
550 // =======================================================================
551 // function : SetScale
552 // purpose  :
553 // =======================================================================
554 void OpenGl_Trihedron::SetScale (const Standard_Real theScale)
555 {
556   if (Abs (myScale - theScale) > Precision::Confusion())
557   {
558     invalidate();
559   }
560   myScale = theScale;
561 }
562
563 // =======================================================================
564 // function : SetSizeRatio
565 // purpose  :
566 // =======================================================================
567 void OpenGl_Trihedron::SetSizeRatio (const Standard_Real theRatio)
568 {
569   if (Abs (Standard_Real(myRatio) - theRatio) > Precision::Confusion())
570   {
571     invalidate();
572   }
573   myRatio = float(theRatio);
574 }
575
576 // =======================================================================
577 // function : SetArrowDiameter
578 // purpose  :
579 // =======================================================================
580 void OpenGl_Trihedron::SetArrowDiameter (const Standard_Real theDiam)
581 {
582   if (Abs (Standard_Real(myDiameter) - theDiam) > Precision::Confusion())
583   {
584     invalidate();
585   }
586   myDiameter = float(theDiam);
587 }
588
589 // =======================================================================
590 // function : SetNbFacets
591 // purpose  :
592 // =======================================================================
593 void OpenGl_Trihedron::SetNbFacets (const Standard_Integer theNbFacets)
594 {
595   if (Abs (myNbFacettes - theNbFacets) > 0)
596   {
597     invalidate();
598   }
599   myNbFacettes = theNbFacets;
600 }
601
602 // =======================================================================
603 // function : SetLabelsColor
604 // purpose  :
605 // =======================================================================
606 void OpenGl_Trihedron::SetLabelsColor (const Quantity_Color& theColor)
607 {
608   myAspectText.ChangeColor().rgb[0] = float(theColor.Red());
609   myAspectText.ChangeColor().rgb[1] = float(theColor.Green());
610   myAspectText.ChangeColor().rgb[2] = float(theColor.Blue());
611 }
612
613 // =======================================================================
614 // function : SetArrowsColors
615 // purpose  :
616 // =======================================================================
617 void OpenGl_Trihedron::SetArrowsColors (const Quantity_Color& theColorX,
618                                         const Quantity_Color& theColorY,
619                                         const Quantity_Color& theColorZ)
620 {
621   myXColor = OpenGl_Vec4 (float(theColorX.Red()), float(theColorX.Green()), float(theColorX.Blue()), 0.6f);
622   myYColor = OpenGl_Vec4 (float(theColorY.Red()), float(theColorY.Green()), float(theColorY.Blue()), 0.6f);
623   myZColor = OpenGl_Vec4 (float(theColorZ.Red()), float(theColorZ.Green()), float(theColorZ.Blue()), 0.6f);
624 }
625
626 // =======================================================================
627 // function : Render
628 // purpose  :
629 // =======================================================================
630 void OpenGl_Trihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
631 {
632   const OpenGl_AspectLine* aPrevAspectLine = theWorkspace->SetAspectLine (&myAspectLine);
633   const OpenGl_AspectText* aPrevAspectText = theWorkspace->SetAspectText (&myAspectText);
634
635   /* check if GL_LIGHTING should be disabled
636   no enabling 'cause it will be done (if necessary: kinda Polygon types )
637   during redrawing structures
638   */
639   if (!theWorkspace->UseGLLight())
640   {
641   #if !defined(GL_ES_VERSION_2_0)
642     glDisable (GL_LIGHTING);
643   #endif
644   }
645
646   const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
647   theWorkspace->ActiveView()->EndTransformPersistence (theWorkspace->GetGlContext());
648   theWorkspace->GetGlContext()->ApplyModelViewMatrix();
649
650   if (myIsWireframe)
651   {
652     redraw (theWorkspace);
653   }
654   else
655   {
656     redrawZBuffer (theWorkspace);
657   }
658
659   // restore aspects
660   if (!aPrevTexture.IsNull())
661   {
662     theWorkspace->EnableTexture (aPrevTexture);
663   }
664
665   theWorkspace->SetAspectText (aPrevAspectText);
666   theWorkspace->SetAspectLine (aPrevAspectLine);
667 }