diff --git a/graf3d/eve/inc/TEveCalo.h b/graf3d/eve/inc/TEveCalo.h
index b7a1749a09ac803a771c574b177e8577f178e468..74fdded0a32621399742fb258dc9cdb5725a33c6 100644
--- a/graf3d/eve/inc/TEveCalo.h
+++ b/graf3d/eve/inc/TEveCalo.h
@@ -96,6 +96,8 @@ public:
    void    SetMaxValAbs(Float_t x) { fMaxValAbs = x; }
    Float_t GetMaxValAbs() const    { return fMaxValAbs; }
 
+   Float_t GetMaxVal() const;
+
    Float_t GetTransitionEta() const;
    Float_t GetTransitionTheta() const;
 
diff --git a/graf3d/eve/inc/TEveCaloLegoGL.h b/graf3d/eve/inc/TEveCaloLegoGL.h
index e97de9f49af67d2456832dd773713f42b3813778..e89553acdc7f053d66d644080678cedd9b5fe92e 100644
--- a/graf3d/eve/inc/TEveCaloLegoGL.h
+++ b/graf3d/eve/inc/TEveCaloLegoGL.h
@@ -15,7 +15,7 @@
 #include "TGLObject.h"
 #include "TEveCaloData.h"
 #include "TGLIncludes.h"
-#include "TGLFontManager.h"
+#include "TGLAxisPainter.h"
 #include <map>
 
 class TEveCaloLego;
@@ -29,22 +29,22 @@ private:
    // cached variables
    mutable Float_t   fDataMax;
    mutable Double_t  fZAxisStep;
-   mutable Double_t  fZAxisMax;
 
    mutable TAxis*    fEtaAxis;
    mutable TAxis*    fPhiAxis;
 
+   mutable TGLAxisAttrib    fXAxisAtt;
+   mutable TGLAxisAttrib    fYAxisAtt;
+   mutable TGLAxisAttrib    fZAxisAtt;
+
+   mutable TGLAxisPainter   fAxisPainter;
+
 protected:
    Int_t   GetGridStep(Int_t axId, TGLRnrCtx &rnrCtx) const;
 
-   void    SetFont(Float_t axis_len, TGLRnrCtx &rnrCtx) const;
-   void    RnrText(const char* txt, Float_t x, Float_t y, Float_t z,
-                   const TGLFont &font, Int_t mode) const;
-
    void    DrawZScales3D(TGLRnrCtx &rnrCtx, Float_t x0, Float_t x1, Float_t y0, Float_t y1) const;
    void    DrawZAxis(TGLRnrCtx &rnrCtx, Float_t azX, Float_t azY) const;
 
-   void    DrawZScales2D(TGLRnrCtx &rnrCtx, Float_t x0, Float_t y0) const;
    void    DrawXYScales(TGLRnrCtx &rnrCtx, Float_t x0, Float_t x1, Float_t y0, Float_t y1) const;
    void    DrawHistBase(TGLRnrCtx &rnrCtx) const;
 
@@ -64,9 +64,6 @@ protected:
 
    TEveCaloLego            *fM;  // Model object.
 
-   mutable TGLFont          fNumFont;
-   mutable TGLFont          fSymbolFont;
-
    // grid density modes
    Int_t                    fNBinSteps;
    Int_t*                   fBinSteps;
diff --git a/graf3d/eve/inc/TEveLegoOverlay.h b/graf3d/eve/inc/TEveLegoOverlay.h
index 72e69ad2b47330705ac5aebd045cec60fde1c640..77c8885fbbdccd57cca2fddf8a56ea9643dd6cde 100644
--- a/graf3d/eve/inc/TEveLegoOverlay.h
+++ b/graf3d/eve/inc/TEveLegoOverlay.h
@@ -13,11 +13,10 @@
 #define ROOT_TEveLegoOverlay
 
 #include "TGLOverlay.h"
-#include "TGLFontManager.h"
 #include "TEveElement.h"
+#include "TGLAxisPainter.h"
 
 class TEveCaloLego;
-class TGLAxis;
 
 class TEveLegoOverlay : public TGLOverlayElement,
                         public TEveElementList
@@ -27,7 +26,6 @@ private:
    TEveLegoOverlay& operator=(const TEveLegoOverlay&); // Not implemented
 
    void DrawSlider(TGLRnrCtx& rnrCtx);
-   void RenderText(const char* txt,Float_t z);
 
    Bool_t SetSliderVal(Event_t* event,TGLRnrCtx& rnrCtx );
 
@@ -45,11 +43,12 @@ protected:
    Bool_t         fShowSlider;
    Float_t        fSliderVal;
 
-   mutable TGLFont  fNumFont;
+   TGLAxisPainter fAxisPainter;
+   TGLAxisAttrib fAxisAtt;
 
 public:
    TEveLegoOverlay();
-   virtual ~TEveLegoOverlay() {}
+   virtual ~TEveLegoOverlay(){}
 
    virtual  Bool_t MouseEnter(TGLOvlSelectRecord& selRec);
    virtual  Bool_t Handle(TGLRnrCtx& rnrCtx, TGLOvlSelectRecord& selRec, Event_t* event);
diff --git a/graf3d/eve/src/TEveCalo.cxx b/graf3d/eve/src/TEveCalo.cxx
index 1a39f90571a947c2993278c687811423b85d98c5..491b49631f9d4fc4b4c36e90fce1678beeb058ef 100644
--- a/graf3d/eve/src/TEveCalo.cxx
+++ b/graf3d/eve/src/TEveCalo.cxx
@@ -171,6 +171,19 @@ void TEveCaloViz::SetPlotEt(Bool_t isEt)
   InvalidateCellIdCache();
 }
 
+//______________________________________________________________________________
+Float_t TEveCaloViz::GetMaxVal() const
+{
+
+   // Get maximum plotted value.
+
+   if (fScaleAbs)
+      return fMaxValAbs;
+   else
+      return fData->GetMaxVal(fPlotEt);
+
+}
+
 //______________________________________________________________________________
 void TEveCaloViz::SetPhiWithRng(Float_t phi, Float_t rng)
 {
diff --git a/graf3d/eve/src/TEveCaloLegoGL.cxx b/graf3d/eve/src/TEveCaloLegoGL.cxx
index 7793113cf3db06502a2c685462ffafede4c8d7f4..bbd5ea29b6ab54338d2862dc91db6620ae68996b 100644
--- a/graf3d/eve/src/TEveCaloLegoGL.cxx
+++ b/graf3d/eve/src/TEveCaloLegoGL.cxx
@@ -20,6 +20,7 @@
 #include "TGLScene.h"
 #include "TGLCamera.h"
 #include "TGLContext.h"
+#include "TGLUtil.h"
 
 #include "TAxis.h"
 #include "TObjString.h"
@@ -39,11 +40,15 @@ TEveCaloLegoGL::TEveCaloLegoGL() :
 
    fDataMax(0),
    fZAxisStep(0),
-   fZAxisMax(0),
 
    fEtaAxis(0),
    fPhiAxis(0),
 
+   fXAxisAtt(),
+   fYAxisAtt(),
+   fZAxisAtt(),
+   fAxisPainter(),
+
    fDLCacheOK(kFALSE),
    fM(0),
 
@@ -56,12 +61,32 @@ TEveCaloLegoGL::TEveCaloLegoGL() :
 
    fDLCache = kFALSE;
 
+   // modes for different levels of zoom in/out.
    fBinSteps = new Int_t[fNBinSteps];
    fBinSteps[0] = 1;
    fBinSteps[1] = 2;
    fBinSteps[2] = 5;
    fBinSteps[3] = 8;
    fBinSteps[4] = 20;
+
+   fXAxisAtt.SetTMNDim(2);
+   fXAxisAtt.SetTextAlign(TGLAxisAttrib::kCenterDown);
+   fXAxisAtt.SetNdivisions(710);
+   fXAxisAtt.SetLabelSize(0.05);
+   fXAxisAtt.SetTitleSize(0.05);
+   fXAxisAtt.SetTitleFontName("symbol");
+   fXAxisAtt.SetTitle("h");
+
+   fYAxisAtt = fXAxisAtt;
+   fYAxisAtt.RefDir().Set(0., 1., 0.);
+   fYAxisAtt.SetNdivisions(510);
+   fYAxisAtt.SetTitle("f");
+
+   fZAxisAtt.RefDir().Set(0., 0., 1.);
+   fZAxisAtt.SetTextAlign(TGLAxisAttrib::kLeft);
+   fZAxisAtt.SetRelativeFontSize(kTRUE);
+   fZAxisAtt.SetLabelSize(0.07);
+   fZAxisAtt.SetTitleSize(0.07);
 }
 
 //______________________________________________________________________________
@@ -238,86 +263,6 @@ void TEveCaloLegoGL::MakeDisplayList() const
    fDLCacheOK=kTRUE;
 }
 
-//______________________________________________________________________________
-void TEveCaloLegoGL::RnrText(const char* txt,
-                             Float_t xa, Float_t ya, Float_t za,
-                             const TGLFont &font, Int_t mode) const
-{
-   // Render text txt at given position, font and alignmnet mode.
-
-   glPushMatrix();
-   glTranslatef(xa, ya, za);
-
-   Float_t llx, lly, llz, urx, ury, urz;
-   font.BBox(txt, llx, lly, llz, urx, ury, urz);
-   if (txt[0] == '-')
-      urx += (urx-llx)/strlen(txt);
- 
-   glRasterPos2i(0, 0);
-   if (mode == 2)
-   {
-      glBitmap(0, 0, 0, 0, -urx, -ury, 0);
-   }
-   else if (mode == 1)
-   {
-      // z label
-      glBitmap(0, 0, 0, 0, -urx, -ury*0.5f, 0);
-   }
-   else
-   {
-      // xy label
-      glBitmap(0, 0, 0, 0,  -urx*0.5f, -ury, 0);
-   }
-
-   font.Render(txt);
-   glPopMatrix();
-}
-
-//______________________________________________________________________________
-void TEveCaloLegoGL::SetFont(Float_t cfs, TGLRnrCtx & rnrCtx) const
-{
-   // Set font size for given axis length.
-
-   Int_t fs =TGLFontManager::GetFontSize(cfs, 12, 36);
-
-   if (fNumFont.GetMode() == TGLFont::kUndef)
-   {
-      rnrCtx.RegisterFont(fs, "arial",  TGLFont::kPixmap, fNumFont);
-      rnrCtx.RegisterFont(fs, "symbol", TGLFont::kPixmap, fSymbolFont);
-   }
-   else if (fNumFont.GetSize() != fs)
-   {
-      rnrCtx.ReleaseFont(fNumFont);
-      rnrCtx.ReleaseFont(fSymbolFont);
-      rnrCtx.RegisterFont(fs, "arial",  TGLFont::kPixmap, fNumFont);
-      rnrCtx.RegisterFont(fs, "symbol", TGLFont::kPixmap, fSymbolFont);
-   }
-}
-
-//______________________________________________________________________________
-void TEveCaloLegoGL::DrawZScales2D(TGLRnrCtx & rnrCtx, Float_t x0, Float_t y0) const
-{
-   // Draw simplified z-axis for top-down view.
-
-   GLdouble x1, y1, x2, y2, z;
-   GLdouble mm[16];
-   GLint    vp[4];
-   glGetDoublev(GL_MODELVIEW_MATRIX, mm);
-   glGetIntegerv(GL_VIEWPORT, vp);
-   const GLdouble *pm = rnrCtx.RefCamera().RefLastNoPickProjM().CArr();
-   gluProject(x0, -TMath::Pi()*0.5, 0, mm, pm, vp, &x1, &y1, &z);
-   gluProject(x0,  TMath::Pi()*0.5, 0, mm, pm, vp, &x2, &y2, &z);
-
-   Float_t etal = TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
-   SetFont(etal*0.1, rnrCtx);
-   TGLUtil::Color(fM->fFontColor);
-   fNumFont.PreRender(kFALSE);
-
-   const char* txt = Form("Et[GeV] %s",TEveUtil::FormAxisValue(fZAxisMax));
-   RnrText(txt, x0*1.05, y0*1.05, 0, fNumFont, 2);
-   fNumFont.PostRender();
-}
-
 //______________________________________________________________________________
 void TEveCaloLegoGL::DrawZAxis(TGLRnrCtx &rnrCtx, Float_t azX, Float_t azY) const
 {
@@ -325,49 +270,20 @@ void TEveCaloLegoGL::DrawZAxis(TGLRnrCtx &rnrCtx, Float_t azX, Float_t azY) cons
 
    glPushMatrix();
    glTranslatef(azX,  azY, 0);
-  
-   // tick mark projected vector is in x dimension 
+
+   // tick mark projected vector is in x dimension
    TGLMatrix modview;
    glGetDoublev(GL_MODELVIEW_MATRIX, modview.Arr());
-   TGLVertex3 worldRef(azX, azY, fZAxisMax*0.5);
-   TGLVector3 off = rnrCtx.RefCamera().ViewportDeltaToWorld(worldRef, -10, 0, &modview);
-
-   // primary tick-marks
-   Int_t np = TMath::CeilNint(fZAxisMax/fZAxisStep);
-   glBegin(GL_LINES);
-   Float_t z = fZAxisStep;
-   for (Int_t i = 0; i < np; ++i)
-   {
-      glVertex3f(0, 0, z);
-      glVertex3f(off.X(), off.Y(), z+off.Z());
-      z += fZAxisStep;
-   }
-
-   // secondary
-   off  = off*0.5f;
-   Double_t omin2, omax2, step2;
-   Int_t div2;
-   THLimitsFinder::Optimize(0, fZAxisStep, fM->GetNZSteps(), omin2, omax2, div2, step2);
-   Double_t z2 = step2;
-   while (z2 < fZAxisMax)
-   {
-      glVertex3f(0, 0, z2);
-      glVertex3f(off.X(), off.Y(), z2+off.Z());
-      z2 += step2;
-   }
-   glEnd();
+   TGLVertex3 worldRef(azX, azY, fDataMax*0.5);
 
-   off *= 4; // label offset
-   fNumFont.PreRender(kFALSE);
-   TGLUtil::Color(fM->fFontColor);
-   for (Int_t i = 1; i < np; ++i)
-      RnrText(TEveUtil::FormAxisValue(i*fZAxisStep), off.X(), off.Y(), i*fZAxisStep+off.Z(), fNumFont, 1);
+   fZAxisAtt.SetAxisColor(fM->fGridColor);
+   fZAxisAtt.SetRng(0, fDataMax);
+   fZAxisAtt.SetNdivisions( fM->fNZSteps*100+10);
+   fZAxisAtt.RefTMOff(0) = rnrCtx.RefCamera().ViewportDeltaToWorld(worldRef, -10, 0, &modview);
+   fZAxisAtt.SetTitle(Form("Et[GeV] %s", TEveUtil::FormAxisValue(fDataMax)));
+   fZAxisAtt.RefTitlePos().Set(0, 0, fDataMax*1.05);
+   fAxisPainter.Paint(rnrCtx, fZAxisAtt);
 
-   const char* txt = TEveUtil::FormAxisValue(fZAxisMax);
-   RnrText(Form("Et[GeV] %s", txt), off.X(), off.Y(), fZAxisMax+off.Z(), fNumFont, 1);
-
-   fNumFont.PostRender();
-  
    glPopMatrix();
 }
 
@@ -431,12 +347,6 @@ void TEveCaloLegoGL::DrawZScales3D(TGLRnrCtx & rnrCtx,
 
    TGLUtil::Color(fM->fGridColor);
 
-   // z axis vertical
-   glBegin(GL_LINES);
-   glVertex3f(azX, azY, 0);
-   glVertex3f(azX, azY, fZAxisMax);
-   glEnd();
-
    if (fM->fBoxMode)
    {
       // get corner closest to eye, excluding left corner
@@ -490,22 +400,22 @@ void TEveCaloLegoGL::DrawZScales3D(TGLRnrCtx & rnrCtx,
 
       // box verticals
       glBegin(GL_LINES);
-      glVertex3f(x0, axY, 0); glVertex3f(x0, axY, fZAxisMax);
-      glVertex3f(x1, axY, 0); glVertex3f(x1, axY, fZAxisMax);
-      glVertex3f(ayX, y0, 0); glVertex3f(ayX, y0, fZAxisMax);
-      glVertex3f(ayX, y1, 0); glVertex3f(ayX, y1, fZAxisMax);
+      glVertex3f(x0, axY, 0); glVertex3f(x0, axY, fDataMax);
+      glVertex3f(x1, axY, 0); glVertex3f(x1, axY, fDataMax);
+      glVertex3f(ayX, y0, 0); glVertex3f(ayX, y0, fDataMax);
+      glVertex3f(ayX, y1, 0); glVertex3f(ayX, y1, fDataMax);
       if (fM->fBoxMode == TEveCaloLego::kFrontBack)
       {
-         glVertex3f(cX, cY, 0); glVertex3f(cX, cY, fZAxisMax);
+         glVertex3f(cX, cY, 0); glVertex3f(cX, cY, fDataMax);
       }
 
       // box top
-      glVertex3f(x0, axY, fZAxisMax); glVertex3f(x1, axY, fZAxisMax);
-      glVertex3f(ayX, y0, fZAxisMax); glVertex3f(ayX, y1, fZAxisMax);
+      glVertex3f(x0, axY, fDataMax); glVertex3f(x1, axY, fDataMax);
+      glVertex3f(ayX, y0, fDataMax); glVertex3f(ayX, y1, fDataMax);
       if (fM->fBoxMode == TEveCaloLego::kFrontBack)
       {
-         glVertex3f(cX, cY, fZAxisMax); glVertex3f(cX, axY, fZAxisMax);
-         glVertex3f(cX, cY, fZAxisMax); glVertex3f(ayX, cY, fZAxisMax);
+         glVertex3f(cX, cY, fDataMax); glVertex3f(cX, axY, fDataMax);
+         glVertex3f(cX, cY, fDataMax); glVertex3f(ayX, cY, fDataMax);
       }
       glEnd();
       glPopAttrib();
@@ -515,7 +425,7 @@ void TEveCaloLegoGL::DrawZScales3D(TGLRnrCtx & rnrCtx,
       glLineStipple(1, 0x5555);
       glEnable(GL_LINE_STIPPLE);
       glBegin(GL_LINES);
-      Int_t nhs = TMath::CeilNint(fZAxisMax/fZAxisStep);
+      Int_t nhs = TMath::CeilNint(fDataMax/fZAxisStep);
       Float_t hz  = 0;
       for (Int_t i = 1; i <= nhs; ++i, hz += fZAxisStep)
       {
@@ -528,16 +438,6 @@ void TEveCaloLegoGL::DrawZScales3D(TGLRnrCtx & rnrCtx,
 
    /**************************************************************************/
 
-   // set font (depending of size projected Z axis)
-   GLdouble dn[3];
-   GLdouble up[3];
-   gluProject(azX, azY, 0, mm, pm, vp, &dn[0], &dn[1], &dn[2]);
-   gluProject(azX, azY, fZAxisMax, mm, pm, vp, &up[0], &up[1], &up[2]);
-   Float_t zAxisLength = TMath::Sqrt((  up[0]-dn[0])*(up[0]-dn[0])
-                                     + (up[1]-dn[1])*(up[1]-dn[1])
-                                     + (up[2]-dn[2])*(up[2]-dn[2]));
-   SetFont(zAxisLength*0.08f, rnrCtx);
-
    DrawZAxis(rnrCtx, azX,  azY);
 
    if (fTowerPicked >= 0)
@@ -621,131 +521,38 @@ void TEveCaloLegoGL::DrawXYScales(TGLRnrCtx & rnrCtx,
    }
 
    Float_t zOff  = -fDataMax*0.03;
-   Float_t zOff2 =  zOff*0.5;
-   
    Float_t yOff  =  0.03*TMath::Sign(y1-y0, axY);
    Float_t xOff  =  0.03*TMath::Sign(x1-x0, ayX);
    Float_t rxy = (fPhiAxis->GetXmax()-fPhiAxis->GetXmin())/(fEtaAxis->GetXmax()-fEtaAxis->GetXmin());
    (rxy>1) ? yOff /= rxy : xOff *=rxy;
 
-   Float_t xOff2 =  xOff*0.5;
-   Float_t yOff2 =  yOff*0.5;
-
-   glPushMatrix();
-   glTranslatef(0, 0, zOff);
-   fNumFont.PreRender(kFALSE);
-   TGLUtil::Color(fM->fFontColor);
-
-   // titles
-   RnrText("h", axtX, axY+2*yOff, zOff, fSymbolFont, 0);
-   RnrText("f", ayX+2*xOff, aytY, zOff, fSymbolFont, 0);
-
-   // X labels
-   Double_t oXmin, oXmax, oXbw;
-   Int_t oXndiv;
-   THLimitsFinder::Optimize(x0, x1, fM->fNZSteps, oXmin, oXmax, oXndiv, oXbw);
-   for (Int_t i = 0; i <= oXndiv; ++i)
-      RnrText(TEveUtil::FormAxisValue(oXmin + oXbw*i), oXmin+oXbw*i, axY + TMath::Sign(yOff*1.5f,axY), 0, fNumFont, 0);
-
-   // Y labels
-   Double_t oYmin, oYmax, oYbw;
-   Int_t oYndiv;
-   THLimitsFinder::Optimize(y0, y1, fM->fNZSteps, oYmin, oYmax, oYndiv, oYbw);
-   for (Int_t i = 0; i <= oYndiv; ++i)
-      RnrText(TEveUtil::FormAxisValue(oYmin + oYbw*i), ayX + TMath::Sign(xOff*1.5f,ayX), oYmin+oYbw*i, 0, fNumFont, 0);
-
-   glPopMatrix();
-   fNumFont.PostRender();
-
-
-   /**************************************************************************/
-   // draw X  axis lines
+   if (fXAxisAtt.GetRelativeFontSize() == kFALSE)
+   {
+      fXAxisAtt.SetAbsLabelFontSize(fZAxisAtt.GetAbsLabelFontSize());
+      fXAxisAtt.SetAbsTitleFontSize(Int_t(fZAxisAtt.GetAbsTitleFontSize()*0.8));
+   }
 
+   fXAxisAtt.SetRng(x0, x1);
+   fXAxisAtt.SetAxisColor(fM->fGridColor);
+   fXAxisAtt.RefTMOff(0).Set(0, yOff, 0);
+   fXAxisAtt.RefTMOff(1).Set(0, 0, zOff);
+   fXAxisAtt.RefTitlePos().Set(axtX, 0, 0);
    glPushMatrix();
    glTranslatef(0, axY, 0);
-   glBegin(GL_LINES);
-   // body
-   glVertex3f(x0, 0, 0);
-   glVertex3f(x1, 0, 0);
-   // tick-marks
-   Double_t oXmin2, oXmax2, oXbw2;
-   Int_t oXndiv2;
-   THLimitsFinder::Optimize(oXmin, oXbw+oXmin, fM->fNZSteps, oXmin2, oXmax2, oXndiv2, oXbw2);
-   Float_t xt = oXmin;
-   Float_t xt2;
-   for(Int_t i = 0; i <= oXndiv; ++i)
-   {
-      glVertex3f(xt, 0,    0);
-      glVertex3f(xt, 0,    zOff);
-      glVertex3f(xt, 0,    0);
-      glVertex3f(xt, yOff, 0);
-      xt2 = xt;
-      for (Int_t j = 0; j <= oXndiv2; ++j)
-      {
-         if (xt2 >= x1) break;
-         glVertex3f(xt2, 0,     0);
-         glVertex3f(xt2, 0,     zOff2);
-         glVertex3f(xt2, 0,     0);
-         glVertex3f(xt2, yOff2, 0);
-         xt2 += oXbw2;
-      }
-      xt += oXbw;
-   }
-   xt2 = oXmin;
-   while (xt2 > x0)
-   {
-      glVertex3f(xt2, 0,     0);
-      glVertex3f(xt2, 0,     zOff2);
-      glVertex3f(xt2, 0,     0);
-      glVertex3f(xt2, yOff2, 0);
-      xt2 -= oXbw2;
-   }
-   glEnd();
+   fAxisPainter.Paint(rnrCtx, fXAxisAtt);
    glPopMatrix();
 
-   /**************************************************************************/
-   // Y axis lines
 
+   fYAxisAtt.SetRng(y0, y1);
+   fYAxisAtt.SetAxisColor(fM->fGridColor);
+   fYAxisAtt.RefTMOff(0).Set(xOff, 0, 0);
+   fYAxisAtt.RefTMOff(1).Set(0, 0, zOff);
+   fYAxisAtt.SetAbsLabelFontSize(fXAxisAtt.GetAbsLabelFontSize());
+   fYAxisAtt.SetAbsTitleFontSize(fXAxisAtt.GetAbsTitleFontSize());
+   fYAxisAtt.RefTitlePos().Set(0, aytY, 0);
    glPushMatrix();
    glTranslatef(ayX, 0, 0);
-   glBegin(GL_LINES);
-   // body
-   glVertex3f(0, y0, 0);
-   glVertex3f(0, y1, 0);
-   // tick-marks
-   Double_t oYmin2, oYmax2, oYbw2;
-   Int_t oYndiv2;
-   THLimitsFinder::Optimize(oYmin, oYbw+oYmin, fM->fNZSteps, oYmin2, oYmax2, oYndiv2, oYbw2);
-   Float_t yt = oYmin;
-   Float_t yt2;
-   for (Int_t i = 0; i <= oYndiv; ++i)
-   {
-      glVertex3f(0,    yt, 0);
-      glVertex3f(0,    yt, zOff);
-      glVertex3f(0,    yt, 0);
-      glVertex3f(xOff, yt, 0);
-      yt2 = yt;
-      for (Int_t j=0; j<=oYndiv2; ++j)
-      {
-         if (yt2 >= y1) break;
-         glVertex3f(0,     yt2, 0);
-         glVertex3f(0,     yt2, zOff2);
-         glVertex3f(0,     yt2, 0);
-         glVertex3f(xOff2, yt2, 0);
-         yt2 += oYbw2;
-      }
-      yt += oYbw;
-   }
-   yt2 = oYmin;
-   while (yt2 > y0)
-   {
-      glVertex3f(0,     yt2, 0);
-      glVertex3f(0,     yt2, zOff2);
-      glVertex3f(0,     yt2, 0);
-      glVertex3f(xOff2, yt2, 0);
-      yt2 -= oYbw2;
-   }
-   glEnd();
+   fAxisPainter.Paint(rnrCtx, fYAxisAtt);
    glPopMatrix();
 
 } // DrawXYScales
@@ -781,7 +588,7 @@ Int_t TEveCaloLegoGL::GetGridStep(Int_t axId, TGLRnrCtx &rnrCtx) const
    {
       Double_t bw =  (fPhiAxis->GetXmax()-fPhiAxis->GetXmin())/fPhiAxis->GetNbins();
       for (Int_t i=0; i<fNBinSteps; ++i)
-      {         
+      {
          gluProject(fM->GetEta(), fM->GetPhi(),                 0, mm, pm, vp, &x0, &y0, &z0);
          gluProject(fM->GetEta(), fM->GetPhi()+fBinSteps[i]*bw, 0, mm, pm, vp, &x1, &y1, &z1);
 
@@ -825,6 +632,7 @@ void TEveCaloLegoGL::DrawHistBase(TGLRnrCtx &rnrCtx) const
    glVertex2f(eta0, phi1);
    glVertex2f(eta1, phi1);
 
+   // eta grid
    if ((es == 1 && ps == 1) || fM->fProjection == TEveCaloLego::k3D)
    {
       // original eta
@@ -848,15 +656,15 @@ void TEveCaloLegoGL::DrawHistBase(TGLRnrCtx &rnrCtx) const
       }
    }
 
-   // phi axis
+   // phi grid
    Int_t   nPhi = CeilNint((phi1-phi0)/(fPhiAxis->GetBinWidth(1)*ps));
    Float_t phi, phiStep;
    if (ps>1)
-   { 
+   {
       phiStep = (phi1-phi0)/nPhi;
       phi = phi0;
    }
-   else 
+   else
    {
       phiStep = fPhiAxis->GetBinWidth(1);
       phi = phiStep*CeilNint(phi0/phiStep);
@@ -870,16 +678,19 @@ void TEveCaloLegoGL::DrawHistBase(TGLRnrCtx &rnrCtx) const
 
    glEnd();
 
+
+   // scales
    glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
    glLineWidth(2);
-
-   // axis
    if ( fM->fProjection == TEveCaloLego::k3D || rnrCtx.RefCamera().GetCamBase().GetBaseVec(1).Z() == 0)
       DrawZScales3D(rnrCtx, eta0, eta1, phi0, phi1);
-   else
-      DrawZScales2D(rnrCtx, eta0, phi0);
 
+   if (fM->fProjection == TEveCaloLego::k2D || rnrCtx.RefCamera().GetCamBase().GetBaseVec(1).Z() != 0)
+      fXAxisAtt.SetRelativeFontSize(kTRUE);
+   else
+      fXAxisAtt.SetRelativeFontSize(kFALSE);
    DrawXYScales(rnrCtx, eta0, eta1, phi0, phi1);
+
    glPopAttrib();
 }
 
@@ -917,6 +728,8 @@ void TEveCaloLegoGL::DrawCells2D(TGLRnrCtx & rnrCtx) const
    using namespace TMath;
    static const TEveException eh("TEveCaloLegoGL::DrawCells2D ");
 
+   fM->AssertPalette();
+
    UChar_t col[4];
    Color_t defCol = fM->GetDataSliceColor(0);  // default color is first slice color
    Int_t es = GetGridStep(0, rnrCtx);
@@ -1036,7 +849,7 @@ void TEveCaloLegoGL::DrawCells2D(TGLRnrCtx & rnrCtx) const
             }
          }
       }
-      
+
       Float_t surf = etaStep*phiStep;
       Float_t maxv = 0;
       for (UInt_t i =0; i<vec.size(); i++)
@@ -1048,7 +861,7 @@ void TEveCaloLegoGL::DrawCells2D(TGLRnrCtx & rnrCtx) const
       Float_t scale = fM->fData->GetMaxVal(fM->fPlotEt)/maxv;
       Float_t logMax = Log(maxv+1);
       Float_t scaleLog =fM->fData->GetMaxVal(fM->fPlotEt)/logMax;
-     
+
       // take smallest threshold
       Float_t threshold = fM->GetDataSliceThreshold(0);
       for (Int_t s=1; s<fM->fData->GetNSlices(); s++)
@@ -1057,7 +870,7 @@ void TEveCaloLegoGL::DrawCells2D(TGLRnrCtx & rnrCtx) const
             threshold = fM->GetDataSliceThreshold(s);
       }
 
-      // draw  scaled    
+      // draw  scaled
       Float_t etaW, phiW;
       Int_t cid = 0;
       glBegin(GL_QUADS);
@@ -1117,18 +930,10 @@ void TEveCaloLegoGL::DirectDraw(TGLRnrCtx & rnrCtx) const
       cells3D = kTRUE;
 
    // init cached variables
-   if (fM->fScaleAbs)
-      fDataMax   = fM->fMaxValAbs;
-   else
-      fDataMax   = fM->fData->GetMaxVal(fM->fPlotEt);
-
+   fDataMax = fM->GetMaxVal();
    Int_t ondiv;
    Double_t omin, omax;
    THLimitsFinder::Optimize(0, fDataMax, fM->fNZSteps, omin, omax, ondiv,  fZAxisStep);
-   fZAxisMax = (ondiv)*fZAxisStep;
-   if (fZAxisMax < fDataMax)
-      fZAxisMax += fZAxisStep;
-
 
    // cache
    if (fM->fCellIdCacheOK == kFALSE)
@@ -1138,7 +943,6 @@ void TEveCaloLegoGL::DirectDraw(TGLRnrCtx & rnrCtx) const
    }
    if (cells3D && fDLCacheOK == kFALSE) MakeDisplayList();
 
-
    // modelview matrix
    glPushMatrix();
 
@@ -1179,7 +983,7 @@ void TEveCaloLegoGL::DirectDraw(TGLRnrCtx & rnrCtx) const
          glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
          glDisable(GL_CULL_FACE);
          TGLUtil::ColorTransparency(fM->fPlaneColor, fM->fPlaneTransparency);
-         Float_t zhp = fM->fHPlaneVal*fZAxisMax;
+         Float_t zhp = fM->fHPlaneVal*fDataMax;
          glBegin(GL_POLYGON);
          glVertex3f(fM->fEtaMin, fM->GetPhiMin(), zhp);
          glVertex3f(fM->fEtaMax, fM->GetPhiMin(), zhp);
diff --git a/graf3d/eve/src/TEveLegoOverlay.cxx b/graf3d/eve/src/TEveLegoOverlay.cxx
index 77c2389b58d35519861388f8cfba292f5cd4fce9..d087ac378c121ec4e3b01ef40fad20eb29960fc4 100644
--- a/graf3d/eve/src/TEveLegoOverlay.cxx
+++ b/graf3d/eve/src/TEveLegoOverlay.cxx
@@ -52,24 +52,9 @@ TEveLegoOverlay::TEveLegoOverlay() :
 {
    // Constructor.
 
-}
-
-
-/******************************************************************************/
-void TEveLegoOverlay::RenderText(const char* txt,Float_t y)
-{
-   // Render pixmap text at given y.
-
-   glPushMatrix();
-   glTranslatef(0, y, 0);
-
-   Float_t llx, lly, llz, urx, ury, urz;
-   fNumFont.BBox(txt, llx, lly, llz, urx, ury, urz);
-   glRasterPos2i(0, 0);
-
-   glBitmap(0, 0, 0, 0, -urx, -ury*0.5f, 0);
-   fNumFont.Render(txt);
-   glPopMatrix();
+   fAxisAtt.RefDir().Set(0, 1, 0);
+   fAxisAtt.SetTextAlign(TGLAxisAttrib::kLeft);
+   fAxisAtt.SetLabelSize(0.06);
 }
 
 /******************************************************************************/
@@ -77,51 +62,13 @@ void TEveLegoOverlay::DrawSlider(TGLRnrCtx& rnrCtx)
 {
    // Draw slider and calorimeter Z scale on left side of screen.
 
-   TGLUtil::Color(fCalo->GetFontColor());
-   Float_t off = -0.01; 
-
-   // font
-   TGLRect& wprt = rnrCtx.RefCamera().RefViewport();
-   Float_t cfs =   wprt.Height()*fSliderH*0.07;
-   Int_t fs = TGLFontManager::GetFontSize(cfs);
-   if (fNumFont.GetMode() == TGLFont::kUndef)
-   {
-      rnrCtx.RegisterFont(fs, "arial",  TGLFont::kPixmap, fNumFont);
-   }
-   else if (fNumFont.GetSize() != fs)
-   {
-      rnrCtx.ReleaseFont(fNumFont);
-      rnrCtx.RegisterFont(fs, "arial",  TGLFont::kPixmap, fNumFont);
-   }
-
-   // optimize binning
-   Float_t w = fButtonW*fMenuW*0.5f;
-   glTranslatef(0, fSliderPosY, 0);
-   Int_t nsteps, ndiv;
-   Double_t omin, omax, zmax, tickval;
-   THLimitsFinder::Optimize(0, fCalo->GetData()->GetMaxVal(fCalo->GetPlotEt()), fCalo->GetNZSteps(), omin, omax, ndiv, tickval);
-   nsteps = ndiv+1;
-   zmax = nsteps*tickval;
-   
-   // labels
-   fNumFont.PreRender(kFALSE);
-   glPushMatrix();
-   glTranslatef(3*off, 0, 0);
-   glScalef(1, fSliderH/zmax , 1.);
-   Double_t val = 0;
-   for(Int_t i=0; i<=nsteps; i++)
-   {
-      RenderText(TEveUtil::FormAxisValue(val), val);
-      val+= tickval;
-   }
-   glPopMatrix();
-   fNumFont.PostRender();
-
+   glTranslatef(0, fSliderPosY, 0.5);
 
-  // event handling
+   // event handling
    if (rnrCtx.Selection())
    {
       glLoadName(2);
+      Float_t w = fButtonW*fMenuW*0.5f;
       glBegin(GL_QUADS);
       glVertex2f(-w, 0);
       glVertex2f( w, 0);
@@ -130,50 +77,25 @@ void TEveLegoOverlay::DrawSlider(TGLRnrCtx& rnrCtx)
       glEnd();
    }
 
+   // draw axis
+   Double_t maxVal = fCalo->GetMaxVal();
+   TGLRect& wprt = rnrCtx.RefCamera().RefViewport();
+   Int_t fs = Int_t(wprt.Height()*fSliderH* fAxisAtt.GetLabelSize());
+   fAxisAtt.SetRng(0, maxVal);
+   fAxisAtt.RefTMOff(0).X() = -maxVal*0.03;
+   fAxisAtt.SetAbsLabelFontSize(fs);
 
    glPushMatrix();
-   glScalef(1, fSliderH/zmax , 1.);
-
-   // body
-   glLineWidth(1);
-   glBegin(GL_LINES);
-   glVertex2f(0, 0);
-   glVertex2f(0, zmax);
-   // primary tick-marks
-   Double_t tv1= 0;
-   for (Int_t i = 0; i <= nsteps; ++i)
-   {
-      glVertex2d(0,  tv1);
-      glVertex2d(2*off , tv1);
-      tv1+= tickval;
-   }
-
-   // secondary tick-marks
-   Double_t omin2, zmax2, tickval2;
-   Int_t nsteps2;
-   THLimitsFinder::Optimize(0, tickval, fCalo->GetNZSteps(), omin2, zmax2, nsteps2, tickval2);
-   Int_t nt2 = Int_t(zmax/tickval2);
-   Float_t step2 = zmax/nt2;
-
-   Double_t tv2= 0;
-   for (Int_t i = 0; i <= nt2; ++i)
-   {
-      glVertex2d(0,  tv2);
-      glVertex2d(off , tv2);
-      tv2+= step2;
-   }
-   glEnd();
-
+   glScalef( fSliderH/maxVal, fSliderH/maxVal, 1.);
+   fAxisPainter.Paint(rnrCtx, fAxisAtt);
    glPopMatrix();
-   
 
    // marker
    TGLUtil::Color((fActiveID == 2) ? fActiveCol : 3);
    glPointSize(8);
    glBegin(GL_POINTS);
    glVertex3f(0, fSliderVal*fSliderH, -0.1);
-   glEnd(); 
-
+   glEnd();
 }
 
 /******************************************************************************/
diff --git a/graf3d/gl/inc/LinkDef.h b/graf3d/gl/inc/LinkDef.h
index 77d06fbf97c2f03a21afb2d2b84d677198072c03..bf76f55ffabdd401713aa85fef8fe14d00af93c3 100644
--- a/graf3d/gl/inc/LinkDef.h
+++ b/graf3d/gl/inc/LinkDef.h
@@ -90,6 +90,8 @@
 #pragma link C++ class TGLSphere;
 #pragma link C++ class TGLText;
 #pragma link C++ class TGLAxis;
+#pragma link C++ class TGLAxisAttrib;
+#pragma link C++ class TGLAxisPainter;
 
 #pragma link C++ class TGLSelectionBuffer;
 #pragma link C++ class TGLPlotCoordinates;
diff --git a/graf3d/gl/inc/TGLAxisPainter.h b/graf3d/gl/inc/TGLAxisPainter.h
new file mode 100644
index 0000000000000000000000000000000000000000..7bce56fc59efe47836baa8cf2d466b891c1010c0
--- /dev/null
+++ b/graf3d/gl/inc/TGLAxisPainter.h
@@ -0,0 +1,112 @@
+// @(#)root/eve:$Id$
+// Author: Matevz Tadel 2007
+
+/*************************************************************************
+ * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+#ifndef ROOT_TGLAxisPainter
+#define ROOT_TGLAxisPainter
+
+#include "TAttAxis.h"
+#include "TGLUtil.h"
+#include "TString.h"
+
+class TGLRnrCtx;
+class TGLFont;
+
+class TGLAxisAttrib: public TAttAxis
+{
+   friend class TGLAxisPainter;
+public:
+   enum ETextAlign_e { kCenterDown, kCenterUp, kLeft, kRight };
+
+protected:
+   TGLVector3   fDir;
+   Double_t     fMin;
+   Double_t     fMax;
+
+   Float_t      fTMScale[3];
+   TGLVector3   fTMOff[3];
+   Int_t        fTMNDim;
+
+   ETextAlign_e   fTextAlign;
+
+   Bool_t       fRelativeFontSize;
+   Int_t        fAbsLabelFontSize;
+   Int_t        fAbsTitleFontSize;
+
+   TString      fLabelFontName;
+   TString      fTitleFontName;
+
+   TString      fTitle;
+   TGLVector3   fTitlePos;
+
+public:
+   TGLAxisAttrib();
+   virtual ~TGLAxisAttrib(){}
+  
+   // Getters && Setters
+
+   TGLVector3&  RefDir() { return fDir; }
+   void SetRng(Double_t min, Double_t max) { fMin=min; fMax=max;}
+   void GetRng(Double_t &min, Double_t &max) {min=fMin; max=fMax;}
+
+   TGLVector3&  RefTMOff(Int_t i) { return fTMOff[i]; }
+   void SetTMNDim(Int_t i) {fTMNDim=i;}
+   Int_t GetTMNDim() {return fTMNDim;}
+
+   void SetTextAlign(ETextAlign_e a) {fTextAlign=a;}
+   ETextAlign_e GetTextAlign() const { return fTextAlign;}
+
+   void SetRelativeFontSize(Bool_t x) { fRelativeFontSize=x; }
+   Bool_t GetRelativeFontSize() const {return fRelativeFontSize;}
+
+   void  SetAbsLabelFontSize(Int_t fs) {fAbsLabelFontSize=fs;}
+   Int_t GetAbsLabelFontSize()const {return fAbsLabelFontSize;}
+   void  SetAbsTitleFontSize(Int_t fs) {fAbsTitleFontSize=fs;}
+   Int_t GetAbsTitleFontSize() const {return fAbsTitleFontSize;}
+
+   void SetLabelFontName(const char* name) { fLabelFontName = name; }
+   const char*  GetLabelFontName() const {return fLabelFontName.Data();}
+   void SetTitleFontName(const char* name) { fTitleFontName = name; }
+   const char*  GetTitleFontName() const {return fTitleFontName.Data();}
+
+   void SetTitle(const char* title) {fTitle = title;}
+   const char* GetTitle() const {return fTitle.Data();}
+   TGLVector3& RefTitlePos() {return fTitlePos;}
+
+   // override TAttAxis function
+   virtual void	SetNdivisions(Int_t n, Bool_t /*optim*/=kTRUE) { fNdivisions =n; }
+
+   ClassDef(TGLAxisAttrib, 0); // GL axis attributes.
+};
+
+/**************************************************************************/
+
+class TGLAxisPainter
+{
+private:
+   TGLAxisPainter(const TGLAxisPainter&);            // Not implemented
+   TGLAxisPainter& operator=(const TGLAxisPainter&); // Not implemented
+
+   void RnrText(const char* txt, TGLVector3 pos, TGLFont &font) const;
+   void DrawTick(TGLVector3 &tv, Int_t order) const;
+   const char* FormAxisValue(Float_t x) const;
+
+   TGLAxisAttrib* fAtt;
+
+public:
+   TGLAxisPainter():fAtt(0) {}
+   virtual ~TGLAxisPainter() {}
+
+   void Paint(TGLRnrCtx& ctx, TGLAxisAttrib &atrib);
+
+   ClassDef(TGLAxisPainter, 0); // GL axis painter.
+};
+
+#endif
diff --git a/graf3d/gl/src/TGLAxisPainter.cxx b/graf3d/gl/src/TGLAxisPainter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d32dd3e5b649b2703e074c9a20cdc17f7468e7bc
--- /dev/null
+++ b/graf3d/gl/src/TGLAxisPainter.cxx
@@ -0,0 +1,278 @@
+// @(#)root/eve:$Id$
+// Author: Matevz Tadel 2007
+
+/*************************************************************************
+ * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+#include "TGLAxisPainter.h"
+
+#include "TGLRnrCtx.h"
+#include "TGLCamera.h"
+#include "TGLIncludes.h"
+#include "TGLRnrCtx.h"
+#include "TGLFontManager.h"
+#include "TAxis.h"
+#include "THLimitsFinder.h"
+
+#include "TMath.h"
+
+
+//______________________________________________________________________________
+// Axsis attributes reguired to be drawn in GL.
+//
+
+ClassImp(TGLAxisAttrib);
+
+//______________________________________________________________________________
+TGLAxisAttrib::TGLAxisAttrib() :
+   TAttAxis(),
+
+   fDir(1, 0, 0),
+   fMin(0),
+   fMax(100),
+
+   fTMNDim(1),
+
+   fTextAlign(kCenterDown),
+
+   fRelativeFontSize(kFALSE),
+   fAbsLabelFontSize(24),
+   fAbsTitleFontSize(24),
+
+   fLabelFontName("arial"),
+   fTitleFontName("arial")
+
+{
+   // Constructor.
+
+   fNdivisions = 510;
+   fLabelSize = 0.04;
+
+   fLabelColor = kWhite;
+   fTitleColor = kWhite;
+
+   fTMScale[0] = 1;
+   fTMScale[1] = 0.5;
+   fTMScale[2] = 0.25;
+}
+
+
+//______________________________________________________________________________
+//
+// Utility class to paint axis in GL.
+
+
+ClassImp(TGLAxisPainter);
+
+//______________________________________________________________________________
+const char* TGLAxisPainter::FormAxisValue(Float_t x) const
+{
+   // Returns formatted text suitable for display of value.
+
+   using namespace TMath;
+
+   if (Abs(x) > 1000)
+      return Form("%d", (Int_t) 10*Nint(x/10.0f));
+   if (Abs(x) > 100 || x == Nint(x))
+      return Form("%d", (Int_t) Nint(x));
+   if (Abs(x) > 10)
+      return Form("%.1f", x);
+   if (Abs(x) >= 0.01 )
+      return Form("%.2f", x);
+   return "0";
+}
+
+//______________________________________________________________________________
+inline void TGLAxisPainter::DrawTick(TGLVector3 &tv, Int_t order) const
+{
+   // Draw tick-marks in supprted dimensions.
+
+   for (Int_t dim=0; dim < fAtt->fTMNDim; dim++)
+   {
+      glVertex3dv(tv.Arr());
+      glVertex3dv((tv+fAtt->fTMOff[dim]*fAtt->fTMScale[order]).Arr());
+   }
+}
+
+//______________________________________________________________________________
+void TGLAxisPainter::RnrText(const char* txt, TGLVector3 pos, TGLFont &font) const
+{
+   // Render text at the given position. Make offset depending of text aligment.
+
+   glPushMatrix();
+   glTranslatef(pos.X(), pos.Y(), pos.Z());
+
+   Float_t llx, lly, llz, urx, ury, urz;
+   font.BBox(txt, llx, lly, llz, urx, ury, urz);
+   if (txt[0] == '-')
+      urx += (urx-llx)/strlen(txt);
+
+   Float_t x=0, y=0;
+
+   switch (fAtt->fTextAlign)
+   {
+      case TGLAxisAttrib::kCenterDown:
+         x = -urx*0.5; y = -ury;
+         break;
+      case TGLAxisAttrib::kCenterUp:
+         x = -urx; y = 0;
+         break;
+      case TGLAxisAttrib::kLeft:
+         x = -urx; y =(lly -ury)*0.5;
+         break;
+      case TGLAxisAttrib::kRight:
+         x = 0; y = -ury*0.5;
+         break;
+      default:
+         break;
+   };
+
+   glRasterPos2i(0, 0);
+   glBitmap(0, 0, 0, 0, x, y, 0);
+   font.Render(txt);
+
+   glPopMatrix();
+}
+
+//______________________________________________________________________________
+void TGLAxisPainter::Paint(TGLRnrCtx &rnrCtx, TGLAxisAttrib &att)
+{
+   // Paint axis body, tickmarks and labels.
+
+   if (rnrCtx.Selection() || rnrCtx.Highlight())
+      return;
+
+   fAtt = &att;
+
+   TGLVector3 start = att.fDir*att.fMin;
+   TGLVector3 end = att.fDir*att.fMax;
+
+   // optimise
+   Int_t n1a = TMath::FloorNint(att.fNdivisions/100);
+   Int_t n2a = att.fNdivisions-n1a*100;
+   Int_t bn1, bn2;
+   Double_t bw1, bw2; // bin with
+   Double_t bl1, bh1, bl2, bh2; // bin low, high
+
+   THLimitsFinder::Optimize(att.fMin, att.fMax, n1a, bl1, bh1, bn1, bw1);
+   THLimitsFinder::Optimize(bl1, bl1+bw1, n2a, bl2, bh2, bn2, bw2);
+
+   /**************************************************************************/
+
+   TGLFont font;
+   Double_t len=0;
+   if (att.fRelativeFontSize)
+   {
+      GLdouble mm[16];
+      GLdouble pm[16];
+      GLint    vp[4];
+      glGetDoublev(GL_MODELVIEW_MATRIX,  mm);
+      glGetDoublev(GL_PROJECTION_MATRIX, pm);
+      glGetIntegerv(GL_VIEWPORT, vp);
+
+      GLdouble dn[3];
+      GLdouble up[3];
+      gluProject(start.X(), start.Y(), start.Z(), mm, pm, vp, &dn[0], &dn[1], &dn[2]);
+      gluProject(end.X(), end.Y(), end.Z(), mm, pm, vp, &up[0], &up[1], &up[2]);
+      len = TMath::Sqrt((  up[0]-dn[0])*(up[0]-dn[0])
+                        + (up[1]-dn[1])*(up[1]-dn[1])
+                        + (up[2]-dn[2])*(up[2]-dn[2]));
+   }
+
+   // labels
+   {
+      Int_t fs = att.fRelativeFontSize ? Int_t(att.GetLabelSize()*len):att.fAbsLabelFontSize;
+      att.fAbsLabelFontSize = TGLFontManager::GetFontSize(fs, 12, 36);
+      rnrCtx.RegisterFont(att.fAbsLabelFontSize, att.fLabelFontName.Data(), TGLFont::kPixmap, font);
+
+      TGLUtil::Color(att.fLabelColor);
+      glPushMatrix();
+      TGLVector3 off = (att.fTMOff[0])*2.5; // tmp
+      glTranslated (off.X(), off.Y(), off.Z());
+
+      font.PreRender();
+      TGLVector3 pos  = att.fDir*bl1;
+      TGLVector3 step = att.fDir*bw1;
+      for (Int_t i=0; i<=bn1; i++)
+      {
+         RnrText(FormAxisValue(bl1+i*bw1), pos, font);
+         pos += step;
+      }
+      font.PostRender();
+      glPopMatrix();
+      rnrCtx.ReleaseFont(font);
+   }
+
+
+   // title
+   if (att.fTitle.Length())
+   {
+      Int_t fs = (att.fRelativeFontSize)? Int_t(att.GetTitleSize()*len) : att.fAbsTitleFontSize;
+
+      rnrCtx.RegisterFont(TGLFontManager::GetFontSize(fs, 12, 36),
+                          att.fTitleFontName.Data(), TGLFont::kPixmap, font);
+      TGLUtil::Color(att.fTitleColor);
+      font.PreRender();
+      TGLVector3 pos = att.fTitlePos;
+      pos  += att.fTMOff[0]*2.5;
+      RnrText(att.fTitle.Data(), pos, font);
+      font.PostRender();
+      rnrCtx.ReleaseFont(font);
+   }
+
+   /**************************************************************************/
+
+   TGLUtil::Color(att.fAxisColor);
+   glBegin(GL_LINES);
+
+   // body
+   {
+      glVertex3dv(start.Arr());
+      glVertex3dv(end.Arr());
+   }
+
+   // tick-marks
+   {
+      TGLVector3 tmStep1 = att.fDir*bw1;
+      TGLVector3 tmStep2 = att.fDir*bw2;
+      TGLVector3 tv1 = att.fDir*bl1;
+      TGLVector3 tv2;
+      for (Int_t t1=0; t1<bn1; t1++)
+      {
+         DrawTick(tv1, 0);
+         tv2 = tv1 + att.fDir*(bl2-bl1);
+         for (Int_t t2=0; t2<=bn2; t2++)
+         {
+            DrawTick(tv2, 1);
+            tv2 += tmStep2;
+         }
+         tv1 += tmStep1;
+      }
+
+      // complete last
+      DrawTick(tv1, 0);
+
+      // complete up edges for first order
+      Int_t nc = Int_t((att.fMax-bh1)/bw2);
+      tv2 = att.fDir*bh1;
+      for(Int_t t2=0; t2<=nc; t2++)
+      {
+         DrawTick(tv2, 1);
+         tv2 += tmStep2;
+      }
+      // complete low edges for first order
+      nc = Int_t((bl1-att.fMin)/bw2);
+      tv2 = att.fDir*bl1;
+      for(Int_t t2=0; t2<=nc; t2++)
+      {
+         DrawTick(tv2, 1);
+         tv2 -= tmStep2;
+      }
+   }
+   glEnd();
+}