0024023: Revamp the OCCT Handle -- general
[occt.git] / src / OpenGl / OpenGl_Trihedron.cxx
index 07348fa..93c06ce 100644 (file)
-// File:      OpenGl_Trihedron.cxx
-// Created:   20 September 2011
-// Author:    Sergey ZERCHANINOV
-// Copyright: OPEN CASCADE 2011
+// Created on: 2011-09-20
+// Created by: Sergey ZERCHANINOV
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
-#define QTOCC_PATCH   /* Active QtOPENCASCADE patches */
-
-#include <OpenGl_tgl_all.hxx>
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h> /* pour M_PI */
-
-#include <OpenGl_TextureBox.hxx>
-
-#include <InterfaceGraphic_Graphic3d.hxx>  /* pour CALL_DEF_STRUCTURE */
-#include <InterfaceGraphic_Aspect.hxx>  /* pour CALL_DEF_VIEW  */
-#include <InterfaceGraphic_Visual3d.hxx>
-
-#include <OpenGl_transform_persistence.hxx>
-
-#ifdef HAVE_GL2PS
-#include <gl2ps.h>
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include <OpenGl_Workspace.hxx>
-#include <OpenGl_View.hxx>
 #include <OpenGl_Trihedron.hxx>
 
-IMPLEMENT_STANDARD_HANDLE(OpenGl_Trihedron,MMgt_TShared)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Trihedron,MMgt_TShared)
-
-/*----------------------------------------------------------------------*/
-/*
-* Constantes
-*/ 
-
-#define NO_DEBUG
-#define NO_PRINT
-#define NO_PRINT_MATRIX
+#include <OpenGl_GlCore11.hxx>
 
-#ifndef M_PI
-# define M_PI          3.14159265358979323846
-#endif
+#include <Graphic3d_ArrayOfSegments.hxx>
+#include <Graphic3d_ArrayOfPolylines.hxx>
+#include <Graphic3d_GraphicDriver.hxx>
+#include <OpenGl_View.hxx>
+#include <OpenGl_Workspace.hxx>
+#include <Precision.hxx>
 
-static const CALL_DEF_CONTEXTLINE myDefaultContextLine =
+namespace
 {
-  1, //IsDef
-  1, //IsSet
-  { 1.F, 1.F, 1.F }, //Color
-  Aspect_TOL_SOLID, //LineType
-  1.F //Width
-};
-
-static const CALL_DEF_CONTEXTTEXT myDefaultContextText =
-{
-  1, //IsDef
-  1, //IsSet
-  "Courier", //Font
-  0.3F, //Space
-  1.0F, //Expan
-  { 1.F, 1.F, 1.F }, //Color
-  Aspect_TOST_NORMAL, //Style
-  Aspect_TODT_NORMAL, //DisplayType
-  { 1.F, 1.F, 1.F }, //ColorSubTitle
-  0, //TextZoomable
-  0.F, //TextAngle
-  OSD_FA_Regular //TextFontAspect
-};
-
-/*----------------------------------------------------------------------*/
-/*
-* Variables statiques
-*/
-
-/* Default parameters for ZBUFFER triheron */
-static TEL_COLOUR theXColor = {{ 1.F, 0.F, 0.F, 0.6F }};
-static TEL_COLOUR theYColor = {{ 0.F, 1.F, 0.F, 0.6F }};
-static TEL_COLOUR theZColor = {{ 0.F, 0.F, 1.F, 0.6F }};
-static float theRatio = 0.8f;
-static float theDiameter = 0.05f;
-static int   theNbFacettes = 12;
-
-/*----------------------------------------------------------------------*/
-
-/*
-* affichage d'un triedre non zoomable a partir des index dans les tables
-* des structures non zoomables.
-*
-* Triedre = Objet non Zoomable :
-* on recalcule ses dimensions et son origine en fonction de la taille
-* de la fenetre; on positionne selon le choix de l'init;
-* et on inhibe seulement les translations.
-*
-*/
-
-//call_triedron_redraw
-void OpenGl_Trihedron::Redraw (const Handle(OpenGl_Workspace) &AWorkspace) const
-{
-  const Standard_Real U = AWorkspace->ActiveView()->Height();
-  const Standard_Real V = AWorkspace->ActiveView()->Width();
-
-  /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
-  /* de la dimension la plus petite de la window.                    */ 
-  const GLdouble L = ( U < V ? U : V ) * myScale;
-
-  /*
-  * On inhibe les translations; on conserve les autres transformations.
-  */
-
-  /* on lit les matrices de transformation et de projection de la vue */
-  /* pour annuler les translations (dernieres colonnes des matrices). */
-  GLdouble modelMatrix[4][4];
-  glGetDoublev( GL_MODELVIEW_MATRIX,  (GLdouble *) modelMatrix );
-  GLdouble projMatrix[4][4];
-  glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
-
-  /* on annule la translation qui peut etre affectee a la vue */
-  modelMatrix[3][0] = 0.;
-  modelMatrix[3][1] = 0.;
-  modelMatrix[3][2] = 0.;
-  projMatrix[3][0] = 0.;
-  projMatrix[3][1] = 0.;
-  projMatrix[3][2] = 0.;
-
-  /* sauvegarde du contexte des matrices avant chargement */
-  glMatrixMode (GL_MODELVIEW);
-  glPushMatrix ();
-  glLoadMatrixd( (GLdouble *) modelMatrix );
-  glMatrixMode ( GL_PROJECTION );
-  glPushMatrix ();
-  glLoadMatrixd( (GLdouble *) projMatrix );
-
-  /*
-  * Positionnement de l'origine du triedre selon le choix de l'init
-  */
+  static const OpenGl_TextParam THE_LABEL_PARAMS =
+  {
+    16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
+  };
+}
 
-  /* on fait uniquement une translation de l'origine du Triedre */
+// =======================================================================
+// function : resetTransformations
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::resetTransformations (const Handle(OpenGl_Workspace)& theWorkspace) const
+{
+  const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+  const Handle(OpenGl_View)& aView    = theWorkspace->ActiveView();
+  GLdouble anU = 1.0;
+  GLdouble aV = 1.0;
+  if (aView->Height() < aView->Width())
+  {
+    aV = aView->Width() / aView->Height();
+  }
+  else
+  {
+    anU = aView->Height() / aView->Width();
+  }
 
+  // Reading the transformation matrices and projection of sight
+  // to cancel translations (last columns of matrices).
+  OpenGl_Mat4d aModelMatrix;
+  OpenGl_Mat4d aProjMatrix;
+  aModelMatrix.Convert (aContext->WorldViewState.Current());
+
+  // Cancel the translation that can be assigned to the view
+  aModelMatrix.ChangeValue (0, 3) = 0.0;
+  aModelMatrix.ChangeValue (1, 3) = 0.0;
+  aModelMatrix.ChangeValue (2, 3) = 0.0;
+
+  aProjMatrix.ChangeValue (0, 0) = 2.0 / anU;
+  aProjMatrix.ChangeValue (1, 0) = 0.0;
+  aProjMatrix.ChangeValue (2, 0) = 0.0;
+  aProjMatrix.ChangeValue (3, 0) = 0.0;
+
+  aProjMatrix.ChangeValue (0, 1) = 0.0;
+  aProjMatrix.ChangeValue (1, 1) = 2.0 / aV;
+  aProjMatrix.ChangeValue (2, 1) = 0.0;
+  aProjMatrix.ChangeValue (3, 1) = 0.0;
+
+  aProjMatrix.ChangeValue (0, 2) = 0.0;
+  aProjMatrix.ChangeValue (1, 2) = 0.0;
+  aProjMatrix.ChangeValue (2, 2) = -2.0 * 0.01;
+  aProjMatrix.ChangeValue (3, 2) = 0.0;
+
+  aProjMatrix.ChangeValue (0, 3) = 0.0;
+  aProjMatrix.ChangeValue (1, 3) = 0.0;
+  aProjMatrix.ChangeValue (2, 3) = 0.0;
+  aProjMatrix.ChangeValue (3, 3) = 1.0;
+
+  // Define trihedron position in the view
   switch (myPos)
   {
-    case Aspect_TOTP_LEFT_LOWER :
-      glTranslated( -0.5*U + L , -0.5*V + L , 0. );
+    case Aspect_TOTP_LEFT_LOWER:
+    {
+      OpenGl_Utils::Translate (aProjMatrix,
+        -0.5 * anU + myScale, -0.5 * aV + myScale, 0.0);
       break;
-
-    case Aspect_TOTP_LEFT_UPPER :
-      glTranslated( -0.5*U + L , +0.5*V - L -L/3., 0. );
+    }
+    case Aspect_TOTP_LEFT_UPPER:
+    {
+      OpenGl_Utils::Translate (aProjMatrix,
+        -0.5 * anU + myScale, 0.5 * aV - myScale - myScale / 3.0, 0.0);
       break;
-
-    case Aspect_TOTP_RIGHT_LOWER :
-      glTranslated( 0.5*U - L -L/3. , -0.5*V + L , 0. );
+    }
+    case Aspect_TOTP_RIGHT_LOWER:
+    {
+      OpenGl_Utils::Translate (aProjMatrix,
+        0.5 * anU - myScale - myScale / 3.0, -0.5 * aV + myScale, 0.0);
       break;
-
-    case Aspect_TOTP_RIGHT_UPPER :
-      glTranslated( 0.5*U - L -L/3. , +0.5*V - L -L/3. , 0. );
+    }
+    case Aspect_TOTP_RIGHT_UPPER:
+    {
+      OpenGl_Utils::Translate (aProjMatrix,
+        0.5 * anU - myScale - myScale / 3.0, 0.5 * aV - myScale - myScale / 3.0, 0.0);
       break;
-
-    //case Aspect_TOTP_CENTER :
-    default :
+    }
+    //case Aspect_TOTP_CENTER:
+    default:
       break;
   }
 
-  /* 
-  * Creation du triedre 
-  */
-  const OpenGl_AspectLine *AspectLine = AWorkspace->AspectLine( Standard_True );
-
-#ifdef QTOCC_PATCH /* Fotis Sioutis 2007-11-14 15:06 
-  I have also seen in previous posts that the view trihedron in V3d_WIREFRAME mode 
-  changes colors depending on the state of the view. This behaviour can be easily 
-  corrected by altering call_triedron_redraw function in OpenGl_triedron.c of TKOpengl.
-  The only change needed is to erase glDisable(GL_LIGHTING) that is called before the 
-  Axis name drawing and move this function call just before the initial axis drawing.
-  Below is the code portion with the modification.I don't know if this is considered to 
-  be a bug but anyway i believe it might help some of you out there.*/
-  glDisable(GL_LIGHTING);
-#endif
-
-  /* Position de l'origine */
-  const GLdouble TriedronOrigin[3] = { 0.0, 0.0, 0.0 };
-
-  /* Position des Axes */
-  GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
-  GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
-  GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
-  TriedronAxeX[0] = L ;
-  TriedronAxeY[1] = L ;
-  TriedronAxeZ[2] = L ;
-
-  /* dessin des axes */
-  glBegin(GL_LINES);
-  glVertex3dv( TriedronOrigin );
-  glVertex3dv( TriedronAxeX );
-
-  glVertex3dv( TriedronOrigin );
-  glVertex3dv( TriedronAxeY );
-
-  glVertex3dv( TriedronOrigin );
-  glVertex3dv( TriedronAxeZ );
-  glEnd();
-
-  /* fleches au bout des axes (= cones de la couleur demandee) */
-  const GLdouble l = 0.75*L; /* distance a l'origine */
-  const GLdouble rayon = L/30. ; /* rayon de la base du cone */
-  const int NbFacettes = 12; /* le cone sera compose de 12 facettes triangulaires */
-  const double Angle = 2. * M_PI/ NbFacettes;
-
-  int      ii;
-  GLdouble TriedronCoord[3] = { 1.0, 0.0, 0.0 };
-
-  /* solution FILAIRE des cones au bout des axes : une seule ligne */
-  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-  /* (la couleur est deja initialisee dans AspectLine) */
-  /* FIN de la solution FILAIRE CHOISIE pour les cones des axes */
-
-  /* fleche en X */
-  glBegin(GL_TRIANGLE_FAN);
-  glVertex3dv( TriedronAxeX );
-  TriedronCoord[0] = l;
-  ii = NbFacettes;
-  while (ii >= 0 ) {
-    TriedronCoord[1] = rayon * sin(ii * Angle);
-    TriedronCoord[2] = rayon * cos(ii * Angle);
-    glVertex3dv( TriedronCoord );
-    ii--;
-  }
-  glEnd();
-
-  /* fleche en Y */
-  glBegin(GL_TRIANGLE_FAN);
-  glVertex3dv( TriedronAxeY );
-  TriedronCoord[1] = l;
-  ii = NbFacettes;
-  while (ii >= 0 ) {
-    TriedronCoord[0] = rayon * cos(ii * Angle);
-    TriedronCoord[2] = rayon * sin(ii * Angle);
-    glVertex3dv( TriedronCoord );
-    ii--;
-  }
-  glEnd();
-
-  /* fleche en Z */
-  glBegin(GL_TRIANGLE_FAN);
-  glVertex3dv( TriedronAxeZ );
-  TriedronCoord[2] = l;
-  ii = NbFacettes;
-  while (ii >= 0 ) {
-    TriedronCoord[0] = rayon * sin(ii * Angle);
-    TriedronCoord[1] = rayon * cos(ii * Angle);
-    glVertex3dv( TriedronCoord );
-    ii--;
-  }
-  glEnd();
-
-  /* dessin de l'origine */
-  TriedronCoord[2] = 0.0 ;
-  ii = 24 ;
-  const double Angle1 = 2. * M_PI/ ii;
-  glBegin(GL_LINE_LOOP);
-  while (ii >= 0 ) {
-    TriedronCoord[0] = rayon * sin(ii * Angle1);
-    TriedronCoord[1] = rayon * cos(ii * Angle1);
-    glVertex3dv( TriedronCoord );
-    ii--;
-  }  
-  glEnd();
-
-  /* 
-  * Noms des axes et de l'origine
-  */
-  const OpenGl_AspectText *AspectText = AWorkspace->AspectText( Standard_True );
-  glColor3fv (AspectText->Color().rgb);
+  aContext->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
+  aContext->ApplyProjectionMatrix();
 
-  AWorkspace->RenderText (L"X", 0, float(L + rayon),    0.0f,                   float(-rayon));
-  AWorkspace->RenderText (L"Y", 0, float(rayon),        float(L + 3.0 * rayon), float(2.0 * rayon));
-  AWorkspace->RenderText (L"Z", 0, float(-2.0 * rayon), float(0.5 * rayon),     float(L + 3.0 * rayon));
-
-  /* 
-  * restauration du contexte des matrices
-  */
-  glMatrixMode (GL_PROJECTION);
-  glPopMatrix ();
-  glMatrixMode (GL_MODELVIEW);
-  glPopMatrix ();
+  aContext->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
+  aContext->ApplyWorldViewMatrix();
 }
 
-
-/*******************************************************
-*  Draws ZBUFFER trihedron mode
-*******************************************************/
-//call_zbuffer_triedron_redraw
-void OpenGl_Trihedron::RedrawZBuffer (const Handle(OpenGl_Workspace) &AWorkspace) const
+// =======================================================================
+// function : redraw
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::redraw (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  const Standard_Real U = AWorkspace->ActiveView()->Height();
-  const Standard_Real V = AWorkspace->ActiveView()->Width();
-
-  GLdouble modelMatrix[4][4];
-  glGetDoublev( GL_MODELVIEW_MATRIX,  (GLdouble *) modelMatrix );
-  GLdouble projMatrix[4][4];
-  glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
-
-  /* Check position in the ViewPort */
-#ifdef QTOCC_PATCH /* PCD 29/09/2008 */
-  /* Simple code modification recommended by Fotis Sioutis and Peter Dolbey  */
-  /* to remove the irritating default behaviour of triedrons using V3d_ZBUFFER   */
-  /* which causes the glyph to jump around the screen when the origin moves offscreen. */
-  GLboolean isWithinView = GL_FALSE;
-#else
-  /* Original code */
-  GLint   aViewPort[4];  /* to store view port coordinates */
-  glGetIntegerv(GL_VIEWPORT, aViewPort);
-  GLdouble aWinCoord[3];
-  /* Position de l'origine */
-  const GLdouble TriedronOrigin[3] = { 0.0, 0.0, 0.0 };
-  gluProject(TriedronOrigin[0], TriedronOrigin[1], TriedronOrigin[2],
-             (GLdouble *)modelMatrix, (GLdouble *)projMatrix, aViewPort,
-             &aWinCoord[0], &aWinCoord[1], &aWinCoord[2]);
-
-  GLboolean isWithinView = !((aWinCoord[0]<aViewPort[0]) || (aWinCoord[0]>aViewPort[2]) ||
-                             (aWinCoord[1]<aViewPort[1]) || (aWinCoord[1]>aViewPort[3]));
-#endif
-
-  /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
-  /* de la dimension la plus petite de la window.                    */ 
-  GLdouble L = ( U < V ? U : V ) * myScale;
-
-  if (!isWithinView)
-  {
-    /* Annulate translation matrix */
-    modelMatrix[3][0] = 0.;
-    modelMatrix[3][1] = 0.;
-    modelMatrix[3][2] = 0.;
-    projMatrix[3][0] = 0.;
-    projMatrix[3][1] = 0.;
-    projMatrix[3][2] = 0.;
-
-    /* save matrix */
-    glMatrixMode (GL_MODELVIEW);
-    glPushMatrix ();
-    //glLoadIdentity ();
-    glLoadMatrixd( (GLdouble *) modelMatrix);
-    glMatrixMode ( GL_PROJECTION );
-    glPushMatrix ();
-    //glLoadIdentity();
-    glLoadMatrixd( (GLdouble *) projMatrix);
-
-    /*
-    * Define position in the view
-    */
-    switch (myPos)
-    {
-      case Aspect_TOTP_LEFT_LOWER : 
-        glTranslated( -0.5*U + L , -0.5*V + L , 0. );
-        break;
+  const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+  aContext->WorldViewState.Push();
+  aContext->ProjectionState.Push();
+
+  resetTransformations (theWorkspace);
+
+  // Set trihedron size parameters
+  GLdouble aScale = myScale;
+  aScale *= myRatio;
+  const Standard_Real aLineRatio = 0.75;
+  const GLdouble aLineLength = aScale * aLineRatio;
+  const GLdouble aConeDiametr     = aScale * myDiameter;
+  const GLdouble aConeLength      = aScale * (1.0 - aLineRatio);
+  const GLdouble aRayon = aScale / 30.0;
+
+  // Create primitive line here for changing length
+  if (!myLine.IsInitialized())
+  {
+    Handle(Graphic3d_ArrayOfSegments) aGraphicArray = new Graphic3d_ArrayOfSegments (2);
+    aGraphicArray->AddVertex (0.0, 0.0, 0.0);
+    aGraphicArray->AddVertex (0.0, 0.0, aLineLength);
+    myLine.InitBuffers (aContext, Graphic3d_TOPA_SEGMENTS, aGraphicArray->Indices(),
+                        aGraphicArray->Attributes(),
+                        aGraphicArray->Bounds());
+  }
 
-      case Aspect_TOTP_LEFT_UPPER :
-        glTranslated( -0.5*U + L , +0.5*V - L -L/3. , 0. );
-        break;
+  if (!myCircle.IsInitialized())
+  {
+    const Standard_Integer THE_CIRCLE_SERMENTS_NB = 24;
+    Handle(Graphic3d_ArrayOfPolylines) anCircleArray = new Graphic3d_ArrayOfPolylines (THE_CIRCLE_SERMENTS_NB + 2);
 
-      case Aspect_TOTP_RIGHT_LOWER :
-        glTranslated( 0.5*U - L -L/3. , -0.5*V + L , 0. );
-        break;
+    const Standard_Real THE_CIRCLE_SEGMENT_ANGLE = 2.0 * M_PI / THE_CIRCLE_SERMENTS_NB;
+    for (Standard_Integer anIt = THE_CIRCLE_SERMENTS_NB; anIt >= 0; --anIt)
+    {
+      anCircleArray->AddVertex (aRayon * sin (anIt * THE_CIRCLE_SEGMENT_ANGLE),
+                                aRayon * cos (anIt * THE_CIRCLE_SEGMENT_ANGLE), 0.0);
+    }
+    anCircleArray->AddVertex (aRayon * sin (THE_CIRCLE_SERMENTS_NB * THE_CIRCLE_SEGMENT_ANGLE),
+                              aRayon * cos (THE_CIRCLE_SERMENTS_NB * THE_CIRCLE_SEGMENT_ANGLE), 0.0);
 
-      case Aspect_TOTP_RIGHT_UPPER :
-        glTranslated( 0.5*U - L -L/3. , +0.5*V - L -L/3. , 0. );
-        break;
+    myCircle.InitBuffers (aContext, Graphic3d_TOPA_POLYLINES, anCircleArray->Indices(),
+                          anCircleArray->Attributes(), anCircleArray->Bounds());
+  }
 
-      //case Aspect_TOTP_CENTER :
-      default :
-        break;
-    }
-    L *= myRatio;
+  if (!myDisk.IsInitialized())
+  {
+    myDisk.Init (0.0, static_cast<GLfloat> (aConeDiametr), myNbFacettes, 1);
   }
 
-  const OpenGl_AspectLine *AspectLine = AWorkspace->AspectLine( Standard_True );
-  const TEL_COLOUR &aLineColor = AspectLine->Color();
+  if (!myCone.IsInitialized())
+  {
+    myCone.Init (static_cast<GLfloat> (aConeDiametr), 0.0f, static_cast<GLfloat> (aConeLength), myNbFacettes, 1);
+  }
 
-  /* 
-  * Creation the trihedron
-  */
-#define CYLINDER_LENGTH   0.75f
-
-  const GLuint startList = glGenLists(4);
-  GLUquadricObj* aQuadric = gluNewQuadric();
-
-  const GLboolean aIsDepthEnabled = glIsEnabled(GL_DEPTH_TEST);
-
-#ifndef BUG
-
-  GLboolean aIsDepthMaskEnabled;
-#ifdef QTOCC_PATCH  /*PCD 02/07/07   */
-  /* GL_DEPTH_WRITEMASK is not a valid argument to glIsEnabled, the  */
-  /* original code is shown to be broken when run under an OpenGL debugger  */
-  /* like GLIntercept. This is the correct way to retrieve the mask value.  */
-  glGetBooleanv(GL_DEPTH_WRITEMASK, &aIsDepthMaskEnabled); 
-#else
-  aIsDepthMaskEnabled = glIsEnabled(GL_DEPTH_WRITEMASK);
-#endif
-
-#endif 
-
-  const GLdouble aCylinderLength = L * CYLINDER_LENGTH;
-  const GLdouble aCylinderDiametr = L * myDiameter;
-  const GLdouble aConeDiametr = aCylinderDiametr * 2.;
-  const GLdouble aConeLength = L * (1 - CYLINDER_LENGTH);
-  /* Correct for owerlapping */
-  /*    aCylinderLength += aConeLength - 1.2*aCylinderDiametr*aConeLength/aConeDiametr;*/
-
-  /* Create cylinder for axis */
-  gluQuadricDrawStyle(aQuadric, GLU_FILL); /* smooth shaded */
-  gluQuadricNormals(aQuadric, GLU_FLAT);
-  /* Axis */
-  glNewList(startList, GL_COMPILE);
-  gluCylinder(aQuadric, aCylinderDiametr, aCylinderDiametr, aCylinderLength, myNbFacettes, 1);
-  glEndList();
-  /* Cone */
-  glNewList(startList + 1, GL_COMPILE);
-  gluCylinder(aQuadric, aConeDiametr, 0., aConeLength, myNbFacettes, 1);
-  glEndList();
-  /* Central sphere */
-  glNewList(startList + 2, GL_COMPILE);
-  gluSphere(aQuadric, aCylinderDiametr * 2., myNbFacettes, myNbFacettes);
-  glEndList();
-  /* End disk */
-  gluQuadricOrientation(aQuadric,GLU_INSIDE); /*szv*/
-  glNewList(startList + 3, GL_COMPILE);
-  gluDisk(aQuadric, aCylinderDiametr, aConeDiametr, myNbFacettes, 1/*szv:2*/);
-  glEndList();
-
-  /* Store previous attributes */
-  glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT);
-  glEnable(GL_LIGHTING);
-
-  glCullFace(GL_BACK);
-  glEnable(GL_CULL_FACE);
-
-#ifdef QTOCC_PATCH /*Fotis Sioutis | 2008-01-21 10:55
-  In the function call_zbuffer_triedron_redraw of TKOpengl, 
-  the z buffered trihedron changes colors in case there 
-  is an object in the scene that has an explicit material 
-  attached to it.In the trihedron display loop, 
-  GL_COLOR_MATERIAL is enabled, but only the GL_DIFFUSE 
-  parameter is utilized in glColorMaterial(...).
-  This causes the last ambient,specular and emission values 
-  used, to stay at the stack and applied to the trihedron
-  (which causes the color change).
-  A fix is proposed , to change GL_DIFFUSE to 
-  GL_AMBIENT_AND_DIFFUSE in glColorMaterial call in 
-  line 946.The above of course will leave unchanged 
-  the SPECULAR and EMISSION values.
-  Another proposal which would fix 100% the problem 
-  is to use glMaterial instead of glColor on the trihedron 
-  drawing loop.               */
-  const GLfloat aNULLColor[] = { 0.f, 0.f, 0.f, 0.f }; /* FS 21/01/08 */
-  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, aNULLColor);
-  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, aNULLColor);
-  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, aNULLColor);
-  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.f);
-#endif
-
-  glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-  glEnable(GL_COLOR_MATERIAL);
-
-  if (!aIsDepthEnabled)  {
-    glEnable(GL_DEPTH_TEST);
-#ifndef BUG
-    glClear(GL_DEPTH_BUFFER_BIT);
-#endif
-  }
-#ifdef BUG
-  if (!(aIsDepthEnabled && isWithinView))
-    glClear(GL_DEPTH_BUFFER_BIT);
-#endif
-
-#ifndef BUG
-  if (!aIsDepthMaskEnabled)  {
-    /* This is how the depthmask needs to be re-enabled...*/
-    glDepthMask(GL_TRUE);
-    /* ...and not this stuff below */
-  }
-#endif
-
-  /* Position des Axes */
-  GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
-  GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
-  GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
-  TriedronAxeX[0] = L;
-  TriedronAxeY[1] = L;
-  TriedronAxeZ[2] = L;
-
-  glMatrixMode(GL_MODELVIEW);
-
-#ifdef QTOCC_PATCH /* PCD 17/06/07  */
-  GLint df;
-  glGetIntegerv (GL_DEPTH_FUNC, &df); 
-#else
-  /*
-#define COLOR_REDUCE      0.3f
-#ifdef BUG
-#define ALPHA_REDUCE      0.4f
-#else
-#define ALPHA_REDUCE      1.0f
-#endif
-  //szv:if (isWithinView) {
-  glDepthFunc(GL_GREATER);
-  glPushMatrix();
-  glPushMatrix();
-  glPushMatrix();
-
-  glColor4f(aLineColor.rgb[0]*COLOR_REDUCE, 
-            aLineColor.rgb[1]*COLOR_REDUCE, 
-            aLineColor.rgb[2]*COLOR_REDUCE,
-            ALPHA_REDUCE);
-  glCallList(startList+2);
+  OpenGl_AspectFace anAspectX;
+  OpenGl_AspectFace anAspectY;
+  OpenGl_AspectFace anAspectZ;
+  OpenGl_AspectLine anAspectLine;
+  memcpy (anAspectX.ChangeIntFront().matcol.rgb, myXColor.GetData(), sizeof (TEL_COLOUR));
+  memcpy (anAspectY.ChangeIntFront().matcol.rgb, myYColor.GetData(), sizeof (TEL_COLOUR));
+  memcpy (anAspectZ.ChangeIntFront().matcol.rgb, myZColor.GetData(), sizeof (TEL_COLOUR));
+  OpenGl_Mat4d aModelMatrix;
+  aModelMatrix.Convert (aContext->WorldViewState.Current());
+  OpenGl_Mat4d aModelViewX (aModelMatrix);
+  OpenGl_Mat4d aModelViewY (aModelMatrix);
+  OpenGl_Mat4d aModelViewZ (aModelMatrix);
+
+  // Set line aspect
+  const OpenGl_AspectLine* aCurrentAspectLine = theWorkspace->AspectLine (Standard_True);
+  CALL_DEF_CONTEXTLINE aLineAspect = {1, 1, { 1.F, 1.F, 1.F },  aCurrentAspectLine->Type(), aCurrentAspectLine->Width()};
+  aLineAspect.Color.r = myZColor.r();
+  aLineAspect.Color.g = myZColor.g();
+  aLineAspect.Color.b = myZColor.b();
+  anAspectLine.SetAspect (aLineAspect);
+
+  // Disable depth test and face culling
+  GLboolean wasDepthMaskEnabled = GL_FALSE;
+  GLint aDepthFuncBack = 0, aCullFaceModeBack = GL_BACK;
+  const GLboolean wasDepthEnabled    = aContext->core11fwd->glIsEnabled (GL_DEPTH_TEST);
+  const GLboolean wasCullFaceEnabled = aContext->core11fwd->glIsEnabled (GL_CULL_FACE);
+  aContext->core11fwd->glGetIntegerv (GL_DEPTH_FUNC,      &aDepthFuncBack);
+  aContext->core11fwd->glGetIntegerv (GL_CULL_FACE_MODE,  &aCullFaceModeBack);
+  aContext->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &wasDepthMaskEnabled);
+  if (!wasDepthEnabled)
+  {
+    aContext->core11fwd->glEnable (GL_DEPTH_TEST);
+    aContext->core11fwd->glClear (GL_DEPTH_BUFFER_BIT);
+  }
+  if (!wasDepthMaskEnabled)
+  {
+    aContext->core11fwd->glDepthMask (GL_TRUE);
+  }
+  aContext->core11fwd->glCullFace (GL_BACK);
+  if (!wasCullFaceEnabled)
+  {
+    aContext->core11fwd->glEnable (GL_CULL_FACE);
+  }
+
+  // Origin
+  myCircle.Render (theWorkspace);
 
   // Z axis
-  glColor4f(myZColor.rgb[0]*COLOR_REDUCE, 
-            myZColor.rgb[1]*COLOR_REDUCE, 
-            myZColor.rgb[2]*COLOR_REDUCE,
-            ALPHA_REDUCE);
-  glCallList(startList);
-  glTranslated(0, 0, L * CYLINDER_LENGTH);
-  glCallList(startList + 3);
-  glCallList(startList + 1);
-  glPopMatrix();    
+  const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace(&anAspectZ);
+  theWorkspace->SetAspectLine (&anAspectLine);
+  myLine.Render (theWorkspace);
+  OpenGl_Utils::Translate (aModelViewZ, 0.0, 0.0, aLineLength);
+  aContext->WorldViewState.SetCurrent<Standard_Real>(aModelViewZ);
+  aContext->ApplyWorldViewMatrix();
+  myDisk.Render (theWorkspace);
+  myCone.Render (theWorkspace);
 
   // X axis
-  glRotated(90.0, TriedronAxeY[0], TriedronAxeY[1], TriedronAxeY[2]);
-  glColor4f(myXColor.rgb[0]*COLOR_REDUCE,
-            myXColor.rgb[1]*COLOR_REDUCE, 
-            myXColor.rgb[2]*COLOR_REDUCE,
-            ALPHA_REDUCE);
-  glCallList(startList);
-  glTranslated(0, 0, L * CYLINDER_LENGTH);
-  glCallList(startList + 3);
-  glCallList(startList + 1);
-  glPopMatrix();    
+  theWorkspace->SetAspectFace (&anAspectX);
+  OpenGl_Utils::Rotate (aModelViewX, 90.0, 0.0, aScale, 0.0);
+  aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewX);
+  aContext->ApplyWorldViewMatrix();
+
+  aLineAspect.Color.r = myXColor.r();
+  aLineAspect.Color.g = myXColor.g();
+  aLineAspect.Color.b = myXColor.b();
+  anAspectLine.SetAspect (aLineAspect);
+  theWorkspace->SetAspectLine (&anAspectLine);
+  myLine.Render (theWorkspace);
+  OpenGl_Utils::Translate (aModelViewX, 0.0, 0.0, aLineLength);
+  aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewX);
+  aContext->ApplyWorldViewMatrix();
+  myDisk.Render (theWorkspace);
+  myCone.Render (theWorkspace);
 
   // Y axis
-  glRotated(-90.0, TriedronAxeX[0], TriedronAxeX[1], TriedronAxeX[2]);
-  glColor4f(myYColor.rgb[0]*COLOR_REDUCE, 
-            myYColor.rgb[1]*COLOR_REDUCE, 
-            myYColor.rgb[2]*COLOR_REDUCE,
-            ALPHA_REDUCE);
-  glCallList(startList);
-  glTranslated(0, 0, L * CYLINDER_LENGTH);
-  glCallList(startList + 3);
-  glCallList(startList + 1);
-  glPopMatrix();
-
-  glDepthFunc(GL_LESS);
-  //szv:}
-  */
-#endif
-
-#ifdef QTOCC_PATCH
-  int i;
-  for (i = 0; i < 2; i++) /* PCD 11/02/08 Two pass method */
+  theWorkspace->SetAspectFace (&anAspectY);
+  OpenGl_Utils::Rotate (aModelViewY, -90.0, aScale, 0.0, 0.0);
+  aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewY);
+  aContext->ApplyWorldViewMatrix();
+
+  aLineAspect.Color.r = myYColor.r();
+  aLineAspect.Color.g = myYColor.g();
+  aLineAspect.Color.b = myYColor.b();
+  anAspectLine.SetAspect (aLineAspect);
+  theWorkspace->SetAspectLine (&anAspectLine);
+  myLine.Render (theWorkspace);
+  OpenGl_Utils::Translate (aModelViewY, 0.0, 0.0, aLineLength);
+  aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewY);
+  aContext->ApplyWorldViewMatrix();
+  myDisk.Render (theWorkspace);
+  myCone.Render (theWorkspace);
+
+  // Restore aspects
+  theWorkspace->SetAspectFace (anOldAspectFace);
+
+  if (!wasDepthEnabled)
   {
-    if (i == 0) /*  First pass  */
-    {                          
-      glDepthFunc(GL_ALWAYS); 
-    }
-    else
-    {
-      glDepthFunc(GL_LEQUAL); 
-    }
-#endif
+    aContext->core11fwd->glDisable (GL_DEPTH_TEST);
+  }
+  if (!wasDepthMaskEnabled)
+  {
+    aContext->core11fwd->glDepthMask (GL_FALSE);
+  }
+  if (!wasCullFaceEnabled)
+  {
+    aContext->core11fwd->glDisable (GL_CULL_FACE);
+  }
+  aContext->core11fwd->glCullFace (aCullFaceModeBack);
+
+  // Always write the text
+  aContext->core11fwd->glDepthFunc (GL_ALWAYS);
+
+  // Render labels
+  myLabelX.SetPosition (OpenGl_Vec3 (float (aScale + 2.0 * aRayon), 0.0f, float (-aRayon)));
+  myLabelY.SetPosition (OpenGl_Vec3 (float (aRayon), float (aScale + 3.0 * aRayon), float (2.0 * aRayon)));
+  myLabelZ.SetPosition (OpenGl_Vec3 (float (-2.0 * aRayon), float (0.5 * aRayon), float (aScale + 3.0 * aRayon)));
+  aContext->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
+  aContext->ApplyWorldViewMatrix();
+  myLabelX.Render (theWorkspace);
+  myLabelY.Render (theWorkspace);
+  myLabelZ.Render (theWorkspace);
+
+  aContext->core11fwd->glDepthFunc (aDepthFuncBack);
+  aContext->WorldViewState.Pop();
+  aContext->ProjectionState.Pop();
+  aContext->ApplyProjectionMatrix();
+}
 
-    glPushMatrix();
-    glPushMatrix();
-    glPushMatrix();
+// =======================================================================
+// function : redrawZBuffer
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::redrawZBuffer (const Handle(OpenGl_Workspace)& theWorkspace) const
+{
+  Handle(OpenGl_Context) aContext = theWorkspace->GetGlContext();
+  aContext->WorldViewState.Push();
+  aContext->ProjectionState.Push();
 
-    glColor3fv(aLineColor.rgb);
-    glCallList(startList+2);
+  resetTransformations (theWorkspace);
 
-    // Z axis
-    glColor4fv(myZColor.rgb);
-    glCallList(startList);
-    glTranslated(0, 0, L * CYLINDER_LENGTH);
-    glCallList(startList + 3);
-    glCallList(startList + 1);
-    glPopMatrix();    
+  const GLdouble aScale = myScale * myRatio;
 
-    // X axis
-    glRotated(90.0, TriedronAxeY[0], TriedronAxeY[1], TriedronAxeY[2]);
-    glColor4fv(myXColor.rgb);
-    glCallList(startList);
-    glTranslated(0, 0, L * CYLINDER_LENGTH);
-    glCallList(startList + 3);
-    glCallList(startList + 1);
-    glPopMatrix();    
+  const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
+  const TEL_COLOUR&        aLineColor   = anAspectLine->Color();
 
-    // Y axis
-    glRotated(-90.0, TriedronAxeX[0], TriedronAxeX[1], TriedronAxeX[2]);
-    glColor4fv(myYColor.rgb);
-    glCallList(startList);
-    glTranslated(0, 0, L * CYLINDER_LENGTH);
-    glCallList(startList + 3);
-    glCallList(startList + 1);
-    glPopMatrix();
+  // Create the trihedron
+  const Standard_Real THE_CYLINDER_LENGTH = 0.75;
+  const GLdouble aCylinderLength  = aScale * THE_CYLINDER_LENGTH;
+  const GLdouble aCylinderDiametr = aScale * myDiameter;
+  const GLdouble aConeDiametr     = aCylinderDiametr * 2.0;
+  const GLdouble aConeLength      = aScale * (1.0 - THE_CYLINDER_LENGTH);
 
-#ifdef QTOCC_PATCH
+  // Position des Axes
+  GLdouble aTriedronAxeX[3] = { aScale, 0.0,    0.0 };
+  GLdouble aTriedronAxeY[3] = { 0.0,    aScale, 0.0 };
+  if (!myDisk.IsInitialized())
+  {
+    myDisk.Init (static_cast<GLfloat> (aCylinderDiametr),
+                 static_cast<GLfloat> (aConeDiametr),
+                 myNbFacettes, 1);
   }
-#endif
 
-  if (!aIsDepthEnabled) 
-    glDisable(GL_DEPTH_TEST);
-#ifndef BUG
-  if (!aIsDepthMaskEnabled)
-
-#ifdef QTOCC_PATCH /*PCD 02/07/07   */
-    glDepthMask(GL_FALSE);
-#else
-    glDisable(GL_DEPTH_WRITEMASK);
-#endif
-
-#endif
-  glDisable(GL_CULL_FACE);
-  glDisable(GL_COLOR_MATERIAL);
+  if (!mySphere.IsInitialized())
+  {
+    mySphere.Init (static_cast<GLfloat> (aCylinderDiametr * 2.0), myNbFacettes, myNbFacettes);
+  }
 
-  gluDeleteQuadric(aQuadric);
-  glColor3fv (aLineColor.rgb);
+  if (!myCone.IsInitialized())
+  {
+    myCone.Init (static_cast<GLfloat> (aConeDiametr), 0.0f, static_cast<GLfloat> (aConeLength), myNbFacettes, 1);
+  }
 
-#ifdef QTOCC_PATCH /* PCD 11/02/08 */
-  /* Always write the text */
-  glDepthFunc(GL_ALWAYS); 
-#endif
+  if (!myCylinder.IsInitialized())
+  {
+    myCylinder.Init (static_cast<GLfloat> (aCylinderDiametr),
+                     static_cast<GLfloat> (aCylinderDiametr),
+                     static_cast<GLfloat> (aCylinderLength),
+                     myNbFacettes, 1);
+  }
 
-  glPopAttrib();
+  GLboolean wasDepthMaskEnabled = GL_FALSE;
+  GLint aDepthFuncBack = 0, aCullFaceModeBack = GL_BACK;
+  const GLboolean wasDepthEnabled    = aContext->core11fwd->glIsEnabled (GL_DEPTH_TEST);
+  const GLboolean wasCullFaceEnabled = aContext->core11fwd->glIsEnabled (GL_CULL_FACE);
+  aContext->core11fwd->glGetIntegerv (GL_DEPTH_FUNC,      &aDepthFuncBack);
+  aContext->core11fwd->glGetIntegerv (GL_CULL_FACE_MODE,  &aCullFaceModeBack);
+  aContext->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &wasDepthMaskEnabled);
+  if (!wasDepthEnabled)
+  {
+    aContext->core11fwd->glEnable (GL_DEPTH_TEST);
+    aContext->core11fwd->glClear (GL_DEPTH_BUFFER_BIT);
+  }
+  if (!wasDepthMaskEnabled)
+  {
+    aContext->core11fwd->glDepthMask (GL_TRUE);
+  }
+  aContext->core11fwd->glCullFace (GL_BACK);
+  if (!wasCullFaceEnabled)
+  {
+    aContext->core11fwd->glEnable (GL_CULL_FACE);
+  }
 
-  /* fleches au bout des axes (= cones de la couleur demandee) */
-  //const GLdouble l = 0.75*L; /* distance a l'origine */
-  const GLdouble rayon = L/30. ; /* rayon de la base du cone */
-  //const double Angle = 2. * M_PI/ myNbFacettes;
+  OpenGl_AspectFace anAspectC;
+  OpenGl_AspectFace anAspectX;
+  OpenGl_AspectFace anAspectY;
+  OpenGl_AspectFace anAspectZ;
+  memcpy (anAspectX.ChangeIntFront().matcol.rgb, myXColor.GetData(), sizeof (TEL_COLOUR));
+  memcpy (anAspectY.ChangeIntFront().matcol.rgb, myYColor.GetData(), sizeof (TEL_COLOUR));
+  memcpy (anAspectZ.ChangeIntFront().matcol.rgb, myZColor.GetData(), sizeof (TEL_COLOUR));
+  memcpy (anAspectC.ChangeIntFront().matcol.rgb, aLineColor.rgb,     sizeof (TEL_COLOUR));
+
+  OpenGl_Mat4d aModelMatrix;
+  aModelMatrix.Convert (aContext->WorldViewState.Current());
+  for (Standard_Integer aPass = 0; aPass < 2; ++aPass)
+  {
+    OpenGl_Mat4d aModelViewX (aModelMatrix);
+    OpenGl_Mat4d aModelViewY (aModelMatrix);
+    OpenGl_Mat4d aModelViewZ (aModelMatrix);
+    aContext->core11fwd->glDepthFunc (aPass == 0 ? GL_ALWAYS : GL_LEQUAL);
 
-  glDeleteLists(startList, 4); 
+    const OpenGl_AspectFace* anOldAspect = theWorkspace->SetAspectFace (&anAspectC);
 
-  glDisable(GL_LIGHTING);
+    // Origin
+    aContext->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
+    aContext->ApplyWorldViewMatrix();
+    mySphere.Render (theWorkspace);
 
-  /* 
-  * origine names
-  */
-  const OpenGl_AspectText *AspectText = AWorkspace->AspectText( Standard_True );
-  glColor3fv (AspectText->Color().rgb);
+    // Z axis
+    theWorkspace->SetAspectFace (&anAspectZ);
+    myCylinder.Render (theWorkspace);
+    OpenGl_Utils::Translate (aModelViewZ, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH);
+    aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewZ);
+    aContext->ApplyWorldViewMatrix();
+    myDisk.Render (theWorkspace);
+    myCone.Render (theWorkspace);
 
-  AWorkspace->RenderText (L"X", 0, float(L + rayon),    0.0f,                   float(-rayon));
-  AWorkspace->RenderText (L"Y", 0, float(rayon),        float(L + 3.0 * rayon), float(2.0 * rayon));
-  AWorkspace->RenderText (L"Z", 0, float(-2.0 * rayon), float(0.5 * rayon),     float(L + 3.0 * rayon));
+    // X axis
+    theWorkspace->SetAspectFace (&anAspectX);
+    OpenGl_Utils::Rotate (aModelViewX, 90.0, aTriedronAxeY[0], aTriedronAxeY[1], aTriedronAxeY[2]);
+    aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewX);
+    aContext->ApplyWorldViewMatrix();
+    myCylinder.Render (theWorkspace);
+    OpenGl_Utils::Translate (aModelViewX, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH);
+    aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewX);
+    aContext->ApplyWorldViewMatrix();
+    myDisk.Render (theWorkspace);
+    myCone.Render (theWorkspace);
 
-#ifdef QTOCC_PATCH
-  /*PCD 17/06/07    */
-  glDepthFunc(df);
-#endif
+    // Y axis
+    theWorkspace->SetAspectFace (&anAspectY);
+    OpenGl_Utils::Rotate (aModelViewY, -90.0, aTriedronAxeX[0], aTriedronAxeX[1], aTriedronAxeX[2]);
+    aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewY);
+    aContext->ApplyWorldViewMatrix();
+    myCylinder.Render (theWorkspace);
+    OpenGl_Utils::Translate (aModelViewY, 0.0, 0.0, aScale * THE_CYLINDER_LENGTH);
+    aContext->WorldViewState.SetCurrent<Standard_Real> (aModelViewY);
+    aContext->ApplyWorldViewMatrix();
+    myDisk.Render (theWorkspace);
+    myCone.Render (theWorkspace);
+
+    theWorkspace->SetAspectFace (anOldAspect);
+  }
 
-  if (!isWithinView) { /* restore matrix */
-    glMatrixMode (GL_PROJECTION);
-    glPopMatrix ();
-    glMatrixMode (GL_MODELVIEW);
-    glPopMatrix ();
+  if (!wasDepthEnabled)
+  {
+    aContext->core11fwd->glDisable (GL_DEPTH_TEST);
+  }
+  if (!wasDepthMaskEnabled)
+  {
+    aContext->core11fwd->glDepthMask (GL_FALSE);
   }
+  if (!wasCullFaceEnabled)
+  {
+    aContext->core11fwd->glDisable (GL_CULL_FACE);
+  }
+  aContext->core11fwd->glCullFace (aCullFaceModeBack);
+
+  // Always write the text
+  aContext->core11fwd->glDepthFunc (GL_ALWAYS);
+
+  // draw axes labels
+  const GLdouble rayon = aScale / 30.0;
+  myLabelX.SetPosition (OpenGl_Vec3(float(aScale + 2.0 * rayon), 0.0f,                        float(-rayon)));
+  myLabelY.SetPosition (OpenGl_Vec3(float(rayon),                float(aScale + 3.0 * rayon), float(2.0 * rayon)));
+  myLabelZ.SetPosition (OpenGl_Vec3(float(-2.0 * rayon),         float(0.5 * rayon),          float(aScale + 3.0 * rayon)));
+  aContext->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
+  aContext->ApplyWorldViewMatrix();
+  myLabelX.Render (theWorkspace);
+  myLabelY.Render (theWorkspace);
+  myLabelZ.Render (theWorkspace);
+
+  aContext->core11fwd->glDepthFunc (aDepthFuncBack);
+
+  aContext->WorldViewState.Pop();
+  aContext->ProjectionState.Pop();
+  aContext->ApplyProjectionMatrix();
 }
 
+// =======================================================================
+// function : OpenGl_Trihedron
+// purpose  :
+// =======================================================================
+OpenGl_Trihedron::OpenGl_Trihedron()
+: myPos (Aspect_TOTP_LEFT_LOWER),
+  myScale (1.0),
+  myIsWireframe (Standard_False),
+  myXColor (1.0f, 0.0f, 0.0f, 0.6f),
+  myYColor (0.0f, 1.0f, 0.0f, 0.6f),
+  myZColor (0.0f, 0.0f, 1.0f, 0.6f),
+  myRatio      (0.8f),
+  myDiameter   (0.05f),
+  myNbFacettes (12),
+  myLabelX ("X", OpenGl_Vec3(1.0f, 0.0f, 0.0f), THE_LABEL_PARAMS),
+  myLabelY ("Y", OpenGl_Vec3(0.0f, 1.0f, 0.0f), THE_LABEL_PARAMS),
+  myLabelZ ("Z", OpenGl_Vec3(0.0f, 0.0f, 1.0f), THE_LABEL_PARAMS),
+  myLine   (NULL), // do not register arrays UID - trihedron is not intended to be drawn by Ray Tracing engine
+  myCircle (NULL)
+{
+  const TEL_COLOUR aWhiteColor = {{ 1.0f, 1.0f, 1.0f, 1.0f }};
+  myAspectLine.ChangeColor()    = aWhiteColor;
+  myAspectText.ChangeColor()    = aWhiteColor;
+  myAspectText.ChangeFontName() = "Courier";
+}
 
-/*----------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------*/
-/*
-* Fonctions publiques 
-*/
+// =======================================================================
+// function : ~OpenGl_Trihedron
+// purpose  :
+// =======================================================================
+OpenGl_Trihedron::~OpenGl_Trihedron()
+{
+  //
+}
 
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::Release (OpenGl_Context* theCtx)
+{
+  myLabelX.Release (theCtx);
+  myLabelY.Release (theCtx);
+  myLabelZ.Release (theCtx);
+  myAspectLine.Release (theCtx);
+  myAspectText.Release (theCtx);
+  myCone    .Release (theCtx);
+  myDisk    .Release (theCtx);
+  mySphere  .Release (theCtx);
+  myCylinder.Release (theCtx);
+  myLine.Release (theCtx);
+  myCircle.Release (theCtx);
+}
 
-/*
-* initialisation d'un triedre non zoomable dans une vue.
-* ou modification des valeurs deja initialisees.
-*/
+// =======================================================================
+// function : invalidate
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::invalidate()
+{
+  myCone    .Invalidate();
+  myDisk    .Invalidate();
+  mySphere  .Invalidate();
+  myCylinder.Invalidate();
+  myLine    .Invalidate();
+  myCircle  .Invalidate();
+}
 
-//call_triedron_init
-OpenGl_Trihedron::OpenGl_Trihedron (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor,
-                                  const Standard_Real AScale, const Standard_Boolean AsWireframe)
-: myPos(APosition),
-  myScale(AScale),
-  myIsWireframe(AsWireframe)
+// =======================================================================
+// function : SetScale
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::SetScale (const Standard_Real theScale)
 {
-  Standard_Real R,G,B;
-  Quantity_Color Color(AColor);
-  Color.Values(R,G,B,Quantity_TOC_RGB);
-
-  CALL_DEF_CONTEXTLINE aContextLine = myDefaultContextLine;
-  aContextLine.Color.r = (float)R;
-  aContextLine.Color.g = (float)G;
-  aContextLine.Color.b = (float)B;
-  myAspectLine.SetContext(aContextLine);
-
-  CALL_DEF_CONTEXTTEXT aContextText = myDefaultContextText;
-  aContextText.Color.r = (float)R;
-  aContextText.Color.g = (float)G;
-  aContextText.Color.b = (float)B;
-  myAspectText.SetContext(aContextText);
-
-  myXColor = theXColor;
-  myYColor = theYColor;
-  myZColor = theZColor;
-
-  myRatio = theRatio;
-  myDiameter = theDiameter;
-  myNbFacettes = theNbFacettes;
+  if (Abs (myScale - theScale) > Precision::Confusion())
+  {
+    invalidate();
+  }
+  myScale = theScale;
 }
 
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : SetSizeRatio
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::SetSizeRatio (const Standard_Real theRatio)
+{
+  if (Abs (Standard_Real(myRatio) - theRatio) > Precision::Confusion())
+  {
+    invalidate();
+  }
+  myRatio = float(theRatio);
+}
 
-/*
-* destruction du triedre non zoomable d'une vue.
-*/
+// =======================================================================
+// function : SetArrowDiameter
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::SetArrowDiameter (const Standard_Real theDiam)
+{
+  if (Abs (Standard_Real(myDiameter) - theDiam) > Precision::Confusion())
+  {
+    invalidate();
+  }
+  myDiameter = float(theDiam);
+}
 
-//call_triedron_erase
-OpenGl_Trihedron::~OpenGl_Trihedron ()
+// =======================================================================
+// function : SetNbFacets
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::SetNbFacets (const Standard_Integer theNbFacets)
 {
+  if (Abs (myNbFacettes - theNbFacets) > 0)
+  {
+    invalidate();
+  }
+  myNbFacettes = theNbFacets;
 }
 
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : SetLabelsColor
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::SetLabelsColor (const Quantity_Color& theColor)
+{
+  myAspectText.ChangeColor().rgb[0] = float(theColor.Red());
+  myAspectText.ChangeColor().rgb[1] = float(theColor.Green());
+  myAspectText.ChangeColor().rgb[2] = float(theColor.Blue());
+}
 
-/*
-* affichage d'un triedre non zoomable dans la wks  awsid 
-*
-* Triedre = Objet non Zoomable;
-* on cree cette fonction pour pouvoir travailler par les structures 
-* utilisees par les fonctions Tsm* et TEL_VIEW_REP
-*
-*/
+// =======================================================================
+// function : SetArrowsColors
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::SetArrowsColors (const Quantity_Color& theColorX,
+                                        const Quantity_Color& theColorY,
+                                        const Quantity_Color& theColorZ)
+{
+  myXColor = OpenGl_Vec4 (float(theColorX.Red()), float(theColorX.Green()), float(theColorX.Blue()), 0.6f);
+  myYColor = OpenGl_Vec4 (float(theColorY.Red()), float(theColorY.Green()), float(theColorY.Blue()), 0.6f);
+  myZColor = OpenGl_Vec4 (float(theColorZ.Red()), float(theColorZ.Green()), float(theColorZ.Blue()), 0.6f);
+}
 
-//call_triedron_redraw_from_wsid
-void OpenGl_Trihedron::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  const OpenGl_AspectLine *oldAspectLine = AWorkspace->SetAspectLine(&myAspectLine);
-  const OpenGl_AspectText *oldAspectText = AWorkspace->SetAspectText(&myAspectText);
+  const OpenGl_AspectLine* aPrevAspectLine = theWorkspace->SetAspectLine (&myAspectLine);
+  const OpenGl_AspectText* aPrevAspectText = theWorkspace->SetAspectText (&myAspectText);
 
   /* check if GL_LIGHTING should be disabled
-  no enabling 'cause it will be done (if necessary: kinda Polygon types ) 
+  no enabling 'cause it will be done (if necessary: kinda Polygon types )
   during redrawing structures
   */
-  if (!AWorkspace->UseGLLight())
-    glDisable( GL_LIGHTING );
-
-  /* sauvegarde du contexte (on reste dans le buffer courant) */
-  const GLboolean save_texture_state = IsTextureEnabled();
-  DisableTexture();
+  if (!theWorkspace->UseGLLight())
+  {
+  #if !defined(GL_ES_VERSION_2_0)
+    glDisable (GL_LIGHTING);
+  #endif
+  }
 
-  /* affichage du Triedre Non Zoomable */
-  AWorkspace->ActiveView()->EndTransformPersistence();
+  const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
+  theWorkspace->ActiveView()->EndTransformPersistence (theWorkspace->GetGlContext());
+  theWorkspace->GetGlContext()->ApplyModelViewMatrix();
 
   if (myIsWireframe)
-    Redraw (AWorkspace);
+  {
+    redraw (theWorkspace);
+  }
   else
-    RedrawZBuffer (AWorkspace);
-
-  /* restauration du contexte */
-  if (save_texture_state) EnableTexture();
+  {
+    redrawZBuffer (theWorkspace);
+  }
 
-  AWorkspace->SetAspectText(oldAspectText);
-  AWorkspace->SetAspectLine(oldAspectLine);
-}
+  // restore aspects
+  if (!aPrevTexture.IsNull())
+  {
+    theWorkspace->EnableTexture (aPrevTexture);
+  }
 
-/*----------------------------------------------------------------------*/
-//call_ztriedron_setup
-void OpenGl_Trihedron::Setup (const Quantity_NameOfColor XColor, const Quantity_NameOfColor YColor, const Quantity_NameOfColor ZColor,
-                             const Standard_Real SizeRatio, const Standard_Real AxisDiametr, const Standard_Integer NbFacettes)
-{
-  Standard_Real R,G,B;
-
-  Quantity_Color(XColor).Values(R, G, B, Quantity_TOC_RGB);
-  theXColor.rgb[0] = float (R);
-  theXColor.rgb[1] = float (G);
-  theXColor.rgb[2] = float (B);
-
-  Quantity_Color(YColor).Values(R, G, B, Quantity_TOC_RGB);
-  theYColor.rgb[0] = float (R);
-  theYColor.rgb[1] = float (G);
-  theYColor.rgb[2] = float (B);
-
-  Quantity_Color(ZColor).Values(R, G, B, Quantity_TOC_RGB);
-  theZColor.rgb[0] = float (R);
-  theZColor.rgb[1] = float (G);
-  theZColor.rgb[2] = float (B);
-
-  theRatio = float (SizeRatio);
-  theDiameter = float (AxisDiametr);
-  theNbFacettes = NbFacettes;
+  theWorkspace->SetAspectText (aPrevAspectText);
+  theWorkspace->SetAspectLine (aPrevAspectLine);
 }