54 TGLVertex3::TGLVertex3()
 
   62 TGLVertex3::TGLVertex3(Double_t x, Double_t y, Double_t z)
 
   70 TGLVertex3::TGLVertex3(Double_t* v)
 
   72    Set(v[0], v[1], v[2]);
 
   78 TGLVertex3::TGLVertex3(
const TGLVertex3 & other)
 
   86 TGLVertex3::~TGLVertex3()
 
   93 void TGLVertex3::Shift(TGLVector3 & shift)
 
  103 void TGLVertex3::Shift(Double_t xDelta, Double_t yDelta, Double_t zDelta)
 
  112 void TGLVertex3::Minimum(
const TGLVertex3 & other)
 
  114    fVals[0] = TMath::Min(fVals[0], other.fVals[0]);
 
  115    fVals[1] = TMath::Min(fVals[1], other.fVals[1]);
 
  116    fVals[2] = TMath::Min(fVals[2], other.fVals[2]);
 
  121 void TGLVertex3::Maximum(
const TGLVertex3 & other)
 
  123    fVals[0] = TMath::Max(fVals[0], other.fVals[0]);
 
  124    fVals[1] = TMath::Max(fVals[1], other.fVals[1]);
 
  125    fVals[2] = TMath::Max(fVals[2], other.fVals[2]);
 
  131 void TGLVertex3::Dump()
 const 
  133    std::cout << 
"(" << fVals[0] << 
"," << fVals[1] << 
"," << fVals[2] << 
")" << std::endl;
 
  147 ClassImp(TGLVector3);
 
  152 TGLVector3::TGLVector3(Double_t x, Double_t y, Double_t z) :
 
  160 TGLVector3::TGLVector3(
const Double_t *src) :
 
  161    TGLVertex3(src[0], src[1], src[2])
 
  177 TGLLine3::TGLLine3(
const TGLVertex3 & start, 
const TGLVertex3 & end) :
 
  178    fVertex(start), fVector(end - start)
 
  185 TGLLine3::TGLLine3(
const TGLVertex3 & start, 
const TGLVector3 & vect) :
 
  186    fVertex(start), fVector(vect)
 
  193 void TGLLine3::Set(
const TGLVertex3 & start, 
const TGLVertex3 & end)
 
  196    fVector = end - start;
 
  202 void TGLLine3::Set(
const TGLVertex3 & start, 
const TGLVector3 & vect)
 
  212 void TGLLine3::Draw()
 const 
  214    glBegin(GL_LINE_LOOP);
 
  215    glVertex3dv(fVertex.CArr());
 
  216    glVertex3dv(End().CArr());
 
  231       fX(0), fY(0), fWidth(0), fHeight(0)
 
  238 TGLRect::TGLRect(Int_t x, Int_t y, Int_t width, Int_t height) :
 
  239       fX(x), fY(y), fWidth(width), fHeight(height)
 
  246 TGLRect::TGLRect(Int_t x, Int_t y, UInt_t width, UInt_t height) :
 
  247       fX(x), fY(y), fWidth(width), fHeight(height)
 
  262 void TGLRect::Expand(Int_t x, Int_t y)
 
  270    if (delY > fHeight) {
 
  287 Int_t TGLRect::Diagonal()
 const 
  289    const Double_t w = 
static_cast<Double_t
>(fWidth);
 
  290    const Double_t h = 
static_cast<Double_t
>(fHeight);
 
  291    return TMath::Nint(TMath::Sqrt(w*w + h*h));
 
  298 Rgl::EOverlap TGLRect::Overlap(
const TGLRect & other)
 const 
  302    if ((fX <= other.fX) && (fX + fWidth  >= other.fX + other.fWidth) &&
 
  303        (fY <= other.fY) && (fY + fHeight >= other.fY + other.fHeight))
 
  307    else if ((fX >= other.fX + static_cast<Int_t>(other.fWidth))  ||
 
  308             (fX + static_cast<Int_t>(fWidth) <= other.fX)        ||
 
  309             (fY >= other.fY + static_cast<Int_t>(other.fHeight)) ||
 
  310             (fY + static_cast<Int_t>(fHeight) <= other.fY))
 
  339    Set(1.0, 1.0, 1.0, 0.0);
 
  345 TGLPlane::TGLPlane(
const TGLPlane & other)
 
  354 TGLPlane::TGLPlane(Double_t a, Double_t b, Double_t c, Double_t d)
 
  363 TGLPlane::TGLPlane(Double_t eq[4])
 
  372 TGLPlane::TGLPlane(
const TGLVertex3 & p1, 
const TGLVertex3 & p2,
 
  373                    const TGLVertex3 & p3)
 
  382 TGLPlane::TGLPlane(
const TGLVector3 & v, 
const TGLVertex3 & p)
 
  390 TGLPlane &TGLPlane::operator=(
const TGLPlane &src)
 
  399 void TGLPlane::Normalise()
 
  401    Double_t mag = sqrt(fVals[0]*fVals[0] + fVals[1]*fVals[1] + fVals[2]*fVals[2]);
 
  404       Error(
"TGLPlane::Normalise", 
"trying to normalise plane with zero magnitude normal");
 
  417 void TGLPlane::Dump()
 const 
  419    std::cout.precision(6);
 
  420    std::cout << 
"Plane : " << fVals[0] << 
"x + " << fVals[1] << 
"y + " << fVals[2] << 
"z + " << fVals[3] << std::endl;
 
  426 void TGLPlane::Set(
const TGLPlane & other)
 
  428    fVals[0] = other.fVals[0];
 
  429    fVals[1] = other.fVals[1];
 
  430    fVals[2] = other.fVals[2];
 
  431    fVals[3] = other.fVals[3];
 
  437 void TGLPlane::Set(Double_t a, Double_t b, Double_t c, Double_t d)
 
  449 void TGLPlane::Set(Double_t eq[4])
 
  461 void TGLPlane::Set(
const TGLVector3 & norm, 
const TGLVertex3 & point)
 
  466    fVals[3] = -(fVals[0]*point[0] + fVals[1]*point[1] + fVals[2]*point[2]);
 
  473 void TGLPlane::Set(
const TGLVertex3 & p1, 
const TGLVertex3 & p2, 
const TGLVertex3 & p3)
 
  475    TGLVector3 norm = Cross(p2 - p1, p3 - p1);
 
  482 void TGLPlane::Negate()
 
  484    fVals[0] = -fVals[0];
 
  485    fVals[1] = -fVals[1];
 
  486    fVals[2] = -fVals[2];
 
  487    fVals[3] = -fVals[3];
 
  493 Double_t TGLPlane::DistanceTo(
const TGLVertex3 & vertex)
 const 
  495    return (fVals[0]*vertex[0] + fVals[1]*vertex[1] + fVals[2]*vertex[2] + fVals[3]);
 
  501 TGLVertex3 TGLPlane::NearestOn(
const TGLVertex3 & point)
 const 
  503    TGLVector3 o = Norm() * (Dot(Norm(), TGLVector3(point[0], point[1], point[2])) + D() / Dot(Norm(), Norm()));
 
  504    TGLVertex3 v = point - o;
 
  517 std::pair<Bool_t, TGLLine3> Intersection(
const TGLPlane & p1, 
const TGLPlane & p2)
 
  519    TGLVector3 lineDir = Cross(p1.Norm(), p2.Norm());
 
  521    if (lineDir.Mag() == 0.0) {
 
  522       return std::make_pair(kFALSE, TGLLine3(TGLVertex3(0.0, 0.0, 0.0),
 
  523                                              TGLVector3(0.0, 0.0, 0.0)));
 
  525    TGLVertex3 linePoint = Cross((p1.Norm()*p2.D() - p2.Norm()*p1.D()), lineDir) /
 
  526                            Dot(lineDir, lineDir);
 
  527    return std::make_pair(kTRUE, TGLLine3(linePoint, lineDir));
 
  532 std::pair<Bool_t, TGLVertex3> Intersection(
const TGLPlane & p1, 
const TGLPlane & p2, 
const TGLPlane & p3)
 
  534    Double_t denom = Dot(p1.Norm(), Cross(p2.Norm(), p3.Norm()));
 
  536       return std::make_pair(kFALSE, TGLVertex3(0.0, 0.0, 0.0));
 
  538    TGLVector3 vect = ((Cross(p2.Norm(),p3.Norm())* -p1.D()) -
 
  539                       (Cross(p3.Norm(),p1.Norm())*p2.D()) -
 
  540                       (Cross(p1.Norm(),p2.Norm())*p3.D())) / denom;
 
  541    TGLVertex3 interVert(vect.X(), vect.Y(), vect.Z());
 
  542    return std::make_pair(kTRUE, interVert);
 
  560 std::pair<Bool_t, TGLVertex3> Intersection(
const TGLPlane & plane, 
const TGLLine3 & line, Bool_t extend)
 
  562    Double_t denom = -(plane.A()*line.Vector().X() +
 
  563                       plane.B()*line.Vector().Y() +
 
  564                       plane.C()*line.Vector().Z());
 
  567       return std::make_pair(kFALSE, TGLVertex3(0.0, 0.0, 0.0));
 
  570    Double_t num = plane.A()*line.Start().X() + plane.B()*line.Start().Y() +
 
  571                   plane.C()*line.Start().Z() + plane.D();
 
  572    Double_t factor = num/denom;
 
  575    if (!extend && (factor < 0.0 || factor > 1.0)) {
 
  576       return std::make_pair(kFALSE, TGLVertex3(0.0, 0.0, 0.0));
 
  579    TGLVector3 toPlane = line.Vector() * factor;
 
  580    return std::make_pair(kTRUE, line.Start() + toPlane);
 
  607 TGLMatrix::TGLMatrix()
 
  620 TGLMatrix::TGLMatrix(Double_t x, Double_t y, Double_t z)
 
  623    SetTranslation(x, y, z);
 
  634 TGLMatrix::TGLMatrix(
const TGLVertex3 & translation)
 
  637    SetTranslation(translation);
 
  645 TGLMatrix::TGLMatrix(
const TGLVertex3 & origin, 
const TGLVector3 & zAxis)
 
  649    TGLVector3 zAxisInt(zAxis);
 
  650    zAxisInt.Normalise();
 
  653    if (TMath::Abs(zAxisInt.X()) <= TMath::Abs(zAxisInt.Y()) && TMath::Abs(zAxisInt.X()) <= TMath::Abs(zAxisInt.Z())) {
 
  654       arbAxis.Set(1.0, 0.0, 0.0);
 
  655    } 
else if (TMath::Abs(zAxisInt.Y()) <= TMath::Abs(zAxisInt.X()) && TMath::Abs(zAxisInt.Y()) <= TMath::Abs(zAxisInt.Z())) {
 
  656       arbAxis.Set(0.0, 1.0, 0.0);
 
  658       arbAxis.Set(0.0, 0.0, 1.0);
 
  661    Set(origin, zAxis, Cross(zAxisInt, arbAxis));
 
  669 TGLMatrix::TGLMatrix(
const TGLVertex3 & origin, 
const TGLVector3 & zAxis, 
const TGLVector3 & xAxis)
 
  672    Set(origin, zAxis, xAxis);
 
  680 TGLMatrix::TGLMatrix(
const Double_t vals[16])
 
  688 TGLMatrix::TGLMatrix(
const TGLMatrix & other)
 
  696 TGLMatrix::~TGLMatrix()
 
  703 void TGLMatrix::MultRight(
const TGLMatrix & rhs)
 
  707   for(
int r=0; r<4; ++r, ++C)
 
  709     const Double_t* T = rhs.fVals;
 
  710     for(
int c=0; c<4; ++c, T+=4)
 
  711       B[c] = C[0]*T[0] + C[4]*T[1] + C[8]*T[2] + C[12]*T[3];
 
  712     C[0] = B[0]; C[4] = B[1]; C[8] = B[2]; C[12] = B[3];
 
  719 void TGLMatrix::MultLeft (
const TGLMatrix & lhs)
 
  723    for (
int c=0; c<4; ++c, C+=4)
 
  725       const Double_t* T = lhs.fVals;
 
  726       for(
int r=0; r<4; ++r, ++T)
 
  727          B[r] = T[0]*C[0] + T[4]*C[1] + T[8]*C[2] + T[12]*C[3];
 
  728       C[0] = B[0]; C[1] = B[1]; C[2] = B[2]; C[3] = B[3];
 
  737 void TGLMatrix::Set(
const TGLVertex3 & origin, 
const TGLVector3 & zAxis, 
const TGLVector3 & xAxis)
 
  739    TGLVector3 zAxisInt(zAxis);
 
  740    zAxisInt.Normalise();
 
  742    TGLVector3 xAxisInt(xAxis);
 
  743    xAxisInt.Normalise();
 
  744    TGLVector3 yAxisInt = Cross(zAxisInt, xAxisInt);
 
  746    fVals[0] = xAxisInt.X(); fVals[4] = yAxisInt.X(); fVals[8 ] = zAxisInt.X(); fVals[12] = origin.X();
 
  747    fVals[1] = xAxisInt.Y(); fVals[5] = yAxisInt.Y(); fVals[9 ] = zAxisInt.Y(); fVals[13] = origin.Y();
 
  748    fVals[2] = xAxisInt.Z(); fVals[6] = yAxisInt.Z(); fVals[10] = zAxisInt.Z(); fVals[14] = origin.Z();
 
  749    fVals[3] = 0.0;          fVals[7] = 0.0;          fVals[11] = 0.0;          fVals[15] = 1.0;
 
  756 void TGLMatrix::Set(
const Double_t vals[16])
 
  758    for (UInt_t i=0; i < 16; i++) {
 
  766 void TGLMatrix::SetIdentity()
 
  768    fVals[0] = 1.0; fVals[4] = 0.0; fVals[8 ] = 0.0; fVals[12] = 0.0;
 
  769    fVals[1] = 0.0; fVals[5] = 1.0; fVals[9 ] = 0.0; fVals[13] = 0.0;
 
  770    fVals[2] = 0.0; fVals[6] = 0.0; fVals[10] = 1.0; fVals[14] = 0.0;
 
  771    fVals[3] = 0.0; fVals[7] = 0.0; fVals[11] = 0.0; fVals[15] = 1.0;
 
  777 void TGLMatrix::SetTranslation(Double_t x, Double_t y, Double_t z)
 
  779    SetTranslation(TGLVertex3(x,y,z));
 
  785 void TGLMatrix::SetTranslation(
const TGLVertex3 & translation)
 
  787    fVals[12] = translation[0];
 
  788    fVals[13] = translation[1];
 
  789    fVals[14] = translation[2];
 
  795 TGLVector3 TGLMatrix::GetTranslation()
 const 
  797    return TGLVector3(fVals[12], fVals[13], fVals[14]);
 
  803 void TGLMatrix::Translate(
const TGLVector3 & vect)
 
  805    fVals[12] += vect[0];
 
  806    fVals[13] += vect[1];
 
  807    fVals[14] += vect[2];
 
  814 void TGLMatrix::MoveLF(Int_t ai, Double_t amount)
 
  816    const Double_t *C = fVals + 4*--ai;
 
  817    fVals[12] += amount*C[0]; fVals[13] += amount*C[1]; fVals[14] += amount*C[2];
 
  823 void TGLMatrix::Move3LF(Double_t x, Double_t y, Double_t z)
 
  825    fVals[12] += x*fVals[0] + y*fVals[4] + z*fVals[8];
 
  826    fVals[13] += x*fVals[1] + y*fVals[5] + z*fVals[9];
 
  827    fVals[14] += x*fVals[2] + y*fVals[6] + z*fVals[10];
 
  835 void TGLMatrix::Scale(
const TGLVector3 & scale)
 
  837    TGLVector3 currentScale = GetScale();
 
  840    if (currentScale[0] != 0.0) {
 
  841       fVals[0] *= scale[0]/currentScale[0];
 
  842       fVals[1] *= scale[0]/currentScale[0];
 
  843       fVals[2] *= scale[0]/currentScale[0];
 
  845       Error(
"TGLMatrix::Scale()", 
"zero scale div by zero");
 
  848    if (currentScale[1] != 0.0) {
 
  849       fVals[4] *= scale[1]/currentScale[1];
 
  850       fVals[5] *= scale[1]/currentScale[1];
 
  851       fVals[6] *= scale[1]/currentScale[1];
 
  853       Error(
"TGLMatrix::Scale()", 
"zero scale div by zero");
 
  856    if (currentScale[2] != 0.0) {
 
  857       fVals[8] *= scale[2]/currentScale[2];
 
  858       fVals[9] *= scale[2]/currentScale[2];
 
  859       fVals[10] *= scale[2]/currentScale[2];
 
  861       Error(
"TGLMatrix::Scale()", 
"zero scale div by zero");
 
  871 void TGLMatrix::Rotate(
const TGLVertex3 & pivot, 
const TGLVector3 & axis, Double_t angle)
 
  873    TGLVector3 nAxis = axis;
 
  875    Double_t x = nAxis.X();
 
  876    Double_t y = nAxis.Y();
 
  877    Double_t z = nAxis.Z();
 
  878    Double_t c = TMath::Cos(angle);
 
  879    Double_t s = TMath::Sin(angle);
 
  883    rotMat[ 0] = x*x*(1-c) + c;   rotMat[ 4] = x*y*(1-c) - z*s; rotMat[ 8] = x*z*(1-c) + y*s; rotMat[12] = pivot[0];
 
  884    rotMat[ 1] = y*x*(1-c) + z*s; rotMat[ 5] = y*y*(1-c) + c;   rotMat[ 9] = y*z*(1-c) - x*s; rotMat[13] = pivot[1];
 
  885    rotMat[ 2] = x*z*(1-c) - y*s; rotMat[ 6] = y*z*(1-c) + x*s; rotMat[10] = z*z*(1-c) + c;   rotMat[14] = pivot[2];
 
  886    rotMat[ 3] = 0.0;             rotMat[ 7] = 0.0;             rotMat[11] = 0.0;             rotMat[15] = 1.0;
 
  887    TGLMatrix localToWorld(-pivot);
 
  891    *
this = rotMat * localToWorld * (*this);
 
  898 void TGLMatrix::RotateLF(Int_t i1, Int_t i2, Double_t amount)
 
  901    const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount);
 
  904    --i1 <<= 2; --i2 <<= 2; 
 
  905    for(
int r=0; r<4; ++r, ++c) {
 
  906       b1 = cos*c[i1] + sin*c[i2];
 
  907       b2 = cos*c[i2] - sin*c[i1];
 
  908       c[i1] = b1; c[i2] = b2;
 
  915 void TGLMatrix::RotatePF(Int_t i1, Int_t i2, Double_t amount)
 
  920    const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount);
 
  924    for(
int c=0; c<4; ++c, C+=4) {
 
  925       b1 = cos*C[i1] - sin*C[i2];
 
  926       b2 = cos*C[i2] + sin*C[i1];
 
  927       C[i1] = b1; C[i2] = b2;
 
  934 void TGLMatrix::TransformVertex(TGLVertex3 & vertex)
 const 
  936    TGLVertex3 orig = vertex;
 
  937    for (UInt_t i = 0; i < 3; i++) {
 
  938       vertex[i] = orig[0] * fVals[0+i] + orig[1] * fVals[4+i] +
 
  939                   orig[2] * fVals[8+i] + fVals[12+i];
 
  948 void TGLMatrix::Transpose3x3()
 
  957    Double_t temp = fVals[4];
 
  972 Double_t TGLMatrix::Invert()
 
  976    const Double_t det2_12_01 = M[1]*M[6]  - M[5]*M[2];
 
  977    const Double_t det2_12_02 = M[1]*M[10] - M[9]*M[2];
 
  978    const Double_t det2_12_03 = M[1]*M[14] - M[13]*M[2];
 
  979    const Double_t det2_12_13 = M[5]*M[14] - M[13]*M[6];
 
  980    const Double_t det2_12_23 = M[9]*M[14] - M[13]*M[10];
 
  981    const Double_t det2_12_12 = M[5]*M[10] - M[9]*M[6];
 
  982    const Double_t det2_13_01 = M[1]*M[7]  - M[5]*M[3];
 
  983    const Double_t det2_13_02 = M[1]*M[11] - M[9]*M[3];
 
  984    const Double_t det2_13_03 = M[1]*M[15] - M[13]*M[3];
 
  985    const Double_t det2_13_12 = M[5]*M[11] - M[9]*M[7];
 
  986    const Double_t det2_13_13 = M[5]*M[15] - M[13]*M[7];
 
  987    const Double_t det2_13_23 = M[9]*M[15] - M[13]*M[11];
 
  988    const Double_t det2_23_01 = M[2]*M[7]  - M[6]*M[3];
 
  989    const Double_t det2_23_02 = M[2]*M[11] - M[10]*M[3];
 
  990    const Double_t det2_23_03 = M[2]*M[15] - M[14]*M[3];
 
  991    const Double_t det2_23_12 = M[6]*M[11] - M[10]*M[7];
 
  992    const Double_t det2_23_13 = M[6]*M[15] - M[14]*M[7];
 
  993    const Double_t det2_23_23 = M[10]*M[15] - M[14]*M[11];
 
  996    const Double_t det3_012_012 = M[0]*det2_12_12 - M[4]*det2_12_02 + M[8]*det2_12_01;
 
  997    const Double_t det3_012_013 = M[0]*det2_12_13 - M[4]*det2_12_03 + M[12]*det2_12_01;
 
  998    const Double_t det3_012_023 = M[0]*det2_12_23 - M[8]*det2_12_03 + M[12]*det2_12_02;
 
  999    const Double_t det3_012_123 = M[4]*det2_12_23 - M[8]*det2_12_13 + M[12]*det2_12_12;
 
 1000    const Double_t det3_013_012 = M[0]*det2_13_12 - M[4]*det2_13_02 + M[8]*det2_13_01;
 
 1001    const Double_t det3_013_013 = M[0]*det2_13_13 - M[4]*det2_13_03 + M[12]*det2_13_01;
 
 1002    const Double_t det3_013_023 = M[0]*det2_13_23 - M[8]*det2_13_03 + M[12]*det2_13_02;
 
 1003    const Double_t det3_013_123 = M[4]*det2_13_23 - M[8]*det2_13_13 + M[12]*det2_13_12;
 
 1004    const Double_t det3_023_012 = M[0]*det2_23_12 - M[4]*det2_23_02 + M[8]*det2_23_01;
 
 1005    const Double_t det3_023_013 = M[0]*det2_23_13 - M[4]*det2_23_03 + M[12]*det2_23_01;
 
 1006    const Double_t det3_023_023 = M[0]*det2_23_23 - M[8]*det2_23_03 + M[12]*det2_23_02;
 
 1007    const Double_t det3_023_123 = M[4]*det2_23_23 - M[8]*det2_23_13 + M[12]*det2_23_12;
 
 1008    const Double_t det3_123_012 = M[1]*det2_23_12 - M[5]*det2_23_02 + M[9]*det2_23_01;
 
 1009    const Double_t det3_123_013 = M[1]*det2_23_13 - M[5]*det2_23_03 + M[13]*det2_23_01;
 
 1010    const Double_t det3_123_023 = M[1]*det2_23_23 - M[9]*det2_23_03 + M[13]*det2_23_02;
 
 1011    const Double_t det3_123_123 = M[5]*det2_23_23 - M[9]*det2_23_13 + M[13]*det2_23_12;
 
 1013    const Double_t det = M[0]*det3_123_123 - M[4]*det3_123_023 +
 
 1014       M[8]*det3_123_013 - M[12]*det3_123_012;
 
 1017       Warning(
"TGLMatrix::Invert", 
"matrix is singular.");
 
 1021    const Double_t oneOverDet = 1.0/det;
 
 1022    const Double_t mn1OverDet = - oneOverDet;
 
 1024    M[0]  = det3_123_123 * oneOverDet;
 
 1025    M[4]  = det3_023_123 * mn1OverDet;
 
 1026    M[8]  = det3_013_123 * oneOverDet;
 
 1027    M[12] = det3_012_123 * mn1OverDet;
 
 1029    M[1]  = det3_123_023 * mn1OverDet;
 
 1030    M[5]  = det3_023_023 * oneOverDet;
 
 1031    M[9]  = det3_013_023 * mn1OverDet;
 
 1032    M[13] = det3_012_023 * oneOverDet;
 
 1034    M[2]  = det3_123_013 * oneOverDet;
 
 1035    M[6]  = det3_023_013 * mn1OverDet;
 
 1036    M[10] = det3_013_013 * oneOverDet;
 
 1037    M[14] = det3_012_013 * mn1OverDet;
 
 1039    M[3]  = det3_123_012 * mn1OverDet;
 
 1040    M[7]  = det3_023_012 * oneOverDet;
 
 1041    M[11] = det3_013_012 * mn1OverDet;
 
 1042    M[15] = det3_012_012 * oneOverDet;
 
 1050 TGLVector3 TGLMatrix::Multiply(
const TGLVector3& v, Double_t w)
 const 
 1052    const Double_t* M = fVals;
 
 1054    r.X() = M[0]*v[0] + M[4]*v[1] +  M[8]*v[2] + M[12]*w;
 
 1055    r.Y() = M[1]*v[0] + M[5]*v[1] +  M[9]*v[2] + M[13]*w;
 
 1056    r.Z() = M[2]*v[0] + M[6]*v[1] + M[10]*v[2] + M[14]*w;
 
 1063 TGLVector3 TGLMatrix::Rotate(
const TGLVector3& v)
 const 
 1065    const Double_t* M = fVals;
 
 1067    r.X() = M[0]*v[0] + M[4]*v[1] +  M[8]*v[2];
 
 1068    r.Y() = M[1]*v[0] + M[5]*v[1] +  M[9]*v[2];
 
 1069    r.Z() = M[2]*v[0] + M[6]*v[1] + M[10]*v[2];
 
 1076 void TGLMatrix::MultiplyIP(TGLVector3& v, Double_t w)
 const 
 1078    const Double_t* M = fVals;
 
 1079    Double_t r[3] = { v[0], v[1], v[2] };
 
 1080    v.X() = M[0]*r[0] + M[4]*r[1] +  M[8]*r[2] + M[12]*w;
 
 1081    v.Y() = M[1]*r[0] + M[5]*r[1] +  M[9]*r[2] + M[13]*w;
 
 1082    v.Z() = M[2]*r[0] + M[6]*r[1] + M[10]*r[2] + M[14]*w;
 
 1088 void TGLMatrix::RotateIP(TGLVector3& v)
 const 
 1090    const Double_t* M = fVals;
 
 1091    Double_t r[3] = { v[0], v[1], v[2] };
 
 1092    v.X() = M[0]*r[0] + M[4]*r[1] +  M[8]*r[2];
 
 1093    v.Y() = M[1]*r[0] + M[5]*r[1] +  M[9]*r[2];
 
 1094    v.Z() = M[2]*r[0] + M[6]*r[1] + M[10]*r[2];
 
 1100 TGLVector3 TGLMatrix::GetScale()
 const 
 1102    TGLVector3 x(fVals[0], fVals[1], fVals[2]);
 
 1103    TGLVector3 y(fVals[4], fVals[5], fVals[6]);
 
 1104    TGLVector3 z(fVals[8], fVals[9], fVals[10]);
 
 1105    return TGLVector3(x.Mag(), y.Mag(), z.Mag());
 
 1112 Bool_t TGLMatrix::IsScalingForRender()
 const 
 1115    ss = fVals[0]*fVals[0] + fVals[1]*fVals[1] + fVals[2]*fVals[2];
 
 1116    if (ss < 0.8 || ss > 1.2) 
return kTRUE;
 
 1117    ss = fVals[4]*fVals[4] + fVals[5]*fVals[5] + fVals[6]*fVals[6];
 
 1118    if (ss < 0.8 || ss > 1.2) 
return kTRUE;
 
 1119    ss = fVals[8]*fVals[8] + fVals[9]*fVals[9] + fVals[10]*fVals[10];
 
 1120    if (ss < 0.8 || ss > 1.2) 
return kTRUE;
 
 1133 void TGLMatrix::Dump()
 const 
 1135    std::cout.precision(6);
 
 1136    for (Int_t x = 0; x < 4; x++) {
 
 1138       for (Int_t y = 0; y < 4; y++) {
 
 1139          std::cout << fVals[y*4 + x] << 
" ";
 
 1141       std::cout << 
"]" << std::endl;
 
 1159 TGLColor::TGLColor()
 
 1161    fRGBA[0] = fRGBA[1] = fRGBA[2] = 0;
 
 1169 TGLColor::TGLColor(Int_t r, Int_t g, Int_t b, Int_t a)
 
 1171    SetColor(r, g, b, a);
 
 1177 TGLColor::TGLColor(Float_t r, Float_t g, Float_t b, Float_t a)
 
 1179    SetColor(r, g, b, a);
 
 1185 TGLColor::TGLColor(Color_t color_index, Char_t transparency)
 
 1187    SetColor(color_index, transparency);
 
 1193 TGLColor::TGLColor(
const TGLColor& c)
 
 1195    fRGBA[0] = c.fRGBA[0];
 
 1196    fRGBA[1] = c.fRGBA[1];
 
 1197    fRGBA[2] = c.fRGBA[2];
 
 1198    fRGBA[3] = c.fRGBA[3];
 
 1205 TGLColor& TGLColor::operator=(
const TGLColor& c)
 
 1207    fRGBA[0] = c.fRGBA[0];
 
 1208    fRGBA[1] = c.fRGBA[1];
 
 1209    fRGBA[2] = c.fRGBA[2];
 
 1210    fRGBA[3] = c.fRGBA[3];
 
 1218 Color_t TGLColor::GetColorIndex()
 const 
 1221       fIndex = TColor::GetColor(fRGBA[0], fRGBA[1], fRGBA[2]);
 
 1228 Char_t TGLColor::GetTransparency()
 const 
 1230    return TMath::Nint(100.0*(1.0 - fRGBA[3]/255.0));
 
 1236 void TGLColor::SetColor(Int_t r, Int_t g, Int_t b, Int_t a)
 
 1248 void TGLColor::SetColor(Float_t r, Float_t g, Float_t b, Float_t a)
 
 1250    fRGBA[0] = (UChar_t)(255*r);
 
 1251    fRGBA[1] = (UChar_t)(255*g);
 
 1252    fRGBA[2] = (UChar_t)(255*b);
 
 1253    fRGBA[3] = (UChar_t)(255*a);
 
 1261 void TGLColor::SetColor(Color_t color_index)
 
 1263    TColor* c = gROOT->GetColor(color_index);
 
 1266       fRGBA[0] = (UChar_t)(255*c->GetRed());
 
 1267       fRGBA[1] = (UChar_t)(255*c->GetGreen());
 
 1268       fRGBA[2] = (UChar_t)(255*c->GetBlue());
 
 1269       fIndex   = color_index;
 
 1285 void TGLColor::SetColor(Color_t color_index, Char_t transparency)
 
 1287    UChar_t alpha = (255*(100 - transparency))/100;
 
 1289    TColor* c = gROOT->GetColor(color_index);
 
 1292       fRGBA[0] = (UChar_t)(255*c->GetRed());
 
 1293       fRGBA[1] = (UChar_t)(255*c->GetGreen());
 
 1294       fRGBA[2] = (UChar_t)(255*c->GetBlue());
 
 1296       fIndex   = color_index;
 
 1313 void TGLColor::SetTransparency(Char_t transparency)
 
 1315    fRGBA[3] = (255*(100 - transparency))/100;
 
 1321 TString TGLColor::AsString()
 const 
 1323    return TString::Format(
"rgba:%02hhx/%02hhx/%02hhx/%02hhx",
 
 1324                           fRGBA[0], fRGBA[1], fRGBA[2], fRGBA[3]);
 
 1333 ClassImp(TGLColorSet);
 
 1338 TGLColorSet::TGLColorSet()
 
 1340    StdDarkBackground();
 
 1346 TGLColorSet::TGLColorSet(
const TGLColorSet& s)
 
 1348    fBackground = s.fBackground;
 
 1349    fForeground = s.fForeground;
 
 1350    fOutline    = s.fOutline;
 
 1351    fMarkup     = s.fMarkup;
 
 1352    for (Int_t i = 0; i < 5; ++i)
 
 1353       fSelection[i] = s.fSelection[i];
 
 1359 TGLColorSet& TGLColorSet::operator=(
const TGLColorSet& s)
 
 1361    fBackground = s.fBackground;
 
 1362    fForeground = s.fForeground;
 
 1363    fOutline    = s.fOutline;
 
 1364    fMarkup     = s.fMarkup;
 
 1365    for (Int_t i = 0; i < 5; ++i)
 
 1366       fSelection[i] = s.fSelection[i];
 
 1373 void TGLColorSet::StdDarkBackground()
 
 1375    fBackground .SetColor(0,   0,   0);
 
 1376    fForeground .SetColor(255, 255, 255);
 
 1377    fOutline    .SetColor(240, 255, 240);
 
 1378    fMarkup     .SetColor(200, 200, 200);
 
 1380    fSelection[0].SetColor(  0,   0,   0);
 
 1381    fSelection[1].SetColor(255, 220, 220);
 
 1382    fSelection[2].SetColor(255, 220, 220);
 
 1383    fSelection[3].SetColor(200, 200, 255);
 
 1384    fSelection[4].SetColor(200, 200, 255);
 
 1390 void TGLColorSet::StdLightBackground()
 
 1392    fBackground .SetColor(255, 255, 255);
 
 1393    fForeground .SetColor(0,   0,   0);
 
 1394    fOutline    .SetColor(0,   0,   0);
 
 1395    fMarkup     .SetColor(55,  55,  55);
 
 1397    fSelection[0].SetColor(0,   0,   0);
 
 1398    fSelection[1].SetColor(200, 100, 100);
 
 1399    fSelection[2].SetColor(200, 100, 100);
 
 1400    fSelection[3].SetColor(100, 100, 200);
 
 1401    fSelection[4].SetColor(100, 100, 200);
 
 1412 UInt_t TGLUtil::fgDefaultDrawQuality = 10;
 
 1413 UInt_t TGLUtil::fgDrawQuality        = fgDefaultDrawQuality;
 
 1414 UInt_t TGLUtil::fgColorLockCount     = 0;
 
 1416 Float_t TGLUtil::fgPointSize      = 1.0f;
 
 1417 Float_t TGLUtil::fgLineWidth      = 1.0f;
 
 1418 Float_t TGLUtil::fgPointSizeScale = 1.0f;
 
 1419 Float_t TGLUtil::fgLineWidthScale = 1.0f;
 
 1421 Float_t TGLUtil::fgScreenScalingFactor     = 1.0f;
 
 1422 Float_t TGLUtil::fgPointLineScalingFactor  = 1.0f;
 
 1423 Int_t   TGLUtil::fgPickingRadius           = 1;
 
 1425 const UChar_t TGLUtil::fgRed[4]    = { 230,   0,   0, 255 };
 
 1426 const UChar_t TGLUtil::fgGreen[4]  = {   0, 230,   0, 255 };
 
 1427 const UChar_t TGLUtil::fgBlue[4]   = {   0,   0, 230, 255 };
 
 1428 const UChar_t TGLUtil::fgYellow[4] = { 210, 210,   0, 255 };
 
 1429 const UChar_t TGLUtil::fgWhite[4]  = { 255, 255, 255, 255 };
 
 1430 const UChar_t TGLUtil::fgGrey[4]   = { 128, 128, 128, 100 };
 
 1438 #if defined(__APPLE_CC__) && __APPLE_CC__ > 4000 && __APPLE_CC__ < 5450 && !defined(__INTEL_COMPILER) 
 1439     typedef GLvoid (*tessfuncptr_t)(...);
 
 1440 #elif defined(__linux__) || defined(__FreeBSD__) || defined( __OpenBSD__ ) || defined(__sun) || defined (__CYGWIN__) || defined (__APPLE__) 
 1441     typedef GLvoid (*tessfuncptr_t)();
 
 1442 #elif defined (WIN32) 
 1443     typedef GLvoid (CALLBACK *tessfuncptr_t)();
 
 1445     #error "Error - need to define type tessfuncptr_t for this platform/compiler" 
 1452 class TGLTesselatorWrap
 
 1457    GLUtesselator *fTess;
 
 1459    TGLTesselatorWrap(tessfuncptr_t vertex_func) : fTess(0)
 
 1461       fTess = gluNewTess();
 
 1463          throw std::bad_alloc();
 
 1465 #if defined(__GNUC__) && __GNUC__ >= 8 
 1466 #pragma GCC diagnostic push 
 1467 #pragma GCC diagnostic ignored "-Wcast-function-type" 
 1470       gluTessCallback(fTess, (GLenum)GLU_BEGIN,  (tessfuncptr_t) glBegin);
 
 1471       gluTessCallback(fTess, (GLenum)GLU_END,    (tessfuncptr_t) glEnd);
 
 1472       gluTessCallback(fTess, (GLenum)GLU_VERTEX, vertex_func);
 
 1474 #if defined(__GNUC__) && __GNUC__ >= 8 
 1475 #pragma GCC diagnostic pop 
 1480    virtual ~TGLTesselatorWrap()
 
 1483          gluDeleteTess(fTess);
 
 1493 GLUtesselator* TGLUtil::GetDrawTesselator3fv()
 
 1496 #if defined(__GNUC__) && __GNUC__ >= 8 
 1497 #pragma GCC diagnostic push 
 1498 #pragma GCC diagnostic ignored "-Wcast-function-type" 
 1501    static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex3fv);
 
 1503 #if defined(__GNUC__) && __GNUC__ >= 8 
 1504 #pragma GCC diagnostic pop 
 1507    return singleton.fTess;
 
 1514 GLUtesselator* TGLUtil::GetDrawTesselator4fv()
 
 1517 #if defined(__GNUC__) && __GNUC__ >= 8 
 1518 #pragma GCC diagnostic push 
 1519 #pragma GCC diagnostic ignored "-Wcast-function-type" 
 1522    static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex4fv);
 
 1524 #if defined(__GNUC__) && __GNUC__ >= 8 
 1525 #pragma GCC diagnostic pop 
 1528    return singleton.fTess;
 
 1535 GLUtesselator* TGLUtil::GetDrawTesselator3dv()
 
 1538 #if defined(__GNUC__) && __GNUC__ >= 8 
 1539 #pragma GCC diagnostic push 
 1540 #pragma GCC diagnostic ignored "-Wcast-function-type" 
 1543    static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex3dv);
 
 1545 #if defined(__GNUC__) && __GNUC__ >= 8 
 1546 #pragma GCC diagnostic pop 
 1549    return singleton.fTess;
 
 1556 GLUtesselator* TGLUtil::GetDrawTesselator4dv()
 
 1559 #if defined(__GNUC__) && __GNUC__ >= 8 
 1560 #pragma GCC diagnostic push 
 1561 #pragma GCC diagnostic ignored "-Wcast-function-type" 
 1564    static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex4dv);
 
 1566 #if defined(__GNUC__) && __GNUC__ >= 8 
 1567 #pragma GCC diagnostic pop 
 1570    return singleton.fTess;
 
 1577 void TGLUtil::InitializeIfNeeded()
 
 1579    static Bool_t init_done = kFALSE;
 
 1580    if (init_done) 
return;
 
 1583    fgScreenScalingFactor = gVirtualX->GetOpenGLScalingFactor();
 
 1585    if (strcmp(gEnv->GetValue(
"OpenGL.PointLineScalingFactor", 
"native"), 
"native") == 0)
 
 1587       fgPointLineScalingFactor = fgScreenScalingFactor;
 
 1591       fgPointLineScalingFactor = gEnv->GetValue(
"OpenGL.PointLineScalingFactor", 1.0);
 
 1594    fgPickingRadius = TMath::Nint(gEnv->GetValue(
"OpenGL.PickingRadius", 3.0) * TMath::Sqrt(fgScreenScalingFactor));
 
 1600 UInt_t TGLUtil::GetDrawQuality()
 
 1602    return fgDrawQuality;
 
 1608 void TGLUtil::SetDrawQuality(UInt_t dq)
 
 1616 void TGLUtil::ResetDrawQuality()
 
 1618    fgDrawQuality = fgDefaultDrawQuality;
 
 1624 UInt_t TGLUtil::GetDefaultDrawQuality()
 
 1626    return fgDefaultDrawQuality;
 
 1632 void TGLUtil::SetDefaultDrawQuality(UInt_t dq)
 
 1634    fgDefaultDrawQuality = dq;
 
 1641 Int_t TGLUtil::CheckError(
const char * loc)
 
 1644    const GLubyte *errString;
 
 1646    if ((errCode = glGetError()) != GL_NO_ERROR) {
 
 1647       errString = gluErrorString(errCode);
 
 1649          Error(loc, 
"GL Error %s", (
const char *)errString);
 
 1651          Error(
"TGLUtil::CheckError", 
"GL Error %s", (
const char *)errString);
 
 1664 UInt_t TGLUtil::LockColor()
 
 1666    return ++fgColorLockCount;
 
 1672 UInt_t TGLUtil::UnlockColor()
 
 1674    if (fgColorLockCount)
 
 1677       Error(
"TGLUtil::UnlockColor", 
"fgColorLockCount already 0.");
 
 1678    return fgColorLockCount;
 
 1684 Bool_t TGLUtil::IsColorLocked()
 
 1686    return fgColorLockCount > 0;
 
 1692 void TGLUtil::Color(
const TGLColor& color)
 
 1694    if (fgColorLockCount == 0) glColor4ubv(color.CArr());
 
 1700 void TGLUtil::ColorAlpha(
const TGLColor& color, UChar_t alpha)
 
 1702    if (fgColorLockCount == 0)
 
 1704       glColor4ub(color.GetRed(), color.GetGreen(), color.GetBlue(), alpha);
 
 1711 void TGLUtil::ColorAlpha(
const TGLColor& color, Float_t alpha)
 
 1713    if (fgColorLockCount == 0)
 
 1715       glColor4ub(color.GetRed(), color.GetGreen(), color.GetBlue(), (UChar_t)(255*alpha));
 
 1722 void TGLUtil::ColorAlpha(Color_t color_index, Float_t alpha)
 
 1724    if (fgColorLockCount == 0) {
 
 1725       if (color_index < 0)
 
 1727       TColor* c = gROOT->GetColor(color_index);
 
 1729          glColor4f(c->GetRed(), c->GetGreen(), c->GetBlue(), alpha);
 
 1736 void TGLUtil::ColorTransparency(Color_t color_index, Char_t transparency)
 
 1738    if (fgColorLockCount == 0) {
 
 1739       if (color_index < 0)
 
 1741       TColor* c = gROOT->GetColor(color_index);
 
 1743          glColor4f(c->GetRed(), c->GetGreen(), c->GetBlue(), 1.0f - 0.01f*transparency);
 
 1750 void TGLUtil::Color3ub(UChar_t r, UChar_t g, UChar_t b)
 
 1752    if (fgColorLockCount == 0) glColor3ub(r, g, b);
 
 1758 void TGLUtil::Color4ub(UChar_t r, UChar_t g, UChar_t b, UChar_t a)
 
 1760    if (fgColorLockCount == 0) glColor4ub(r, g, b, a);
 
 1766 void TGLUtil::Color3ubv(
const UChar_t* rgb)
 
 1768    if (fgColorLockCount == 0) glColor3ubv(rgb);
 
 1774 void TGLUtil::Color4ubv(
const UChar_t* rgba)
 
 1776    if (fgColorLockCount == 0) glColor4ubv(rgba);
 
 1782 void TGLUtil::Color3f(Float_t r, Float_t g, Float_t b)
 
 1784    if (fgColorLockCount == 0) glColor3f(r, g, b);
 
 1790 void TGLUtil::Color4f(Float_t r, Float_t g, Float_t b, Float_t a)
 
 1792    if (fgColorLockCount == 0) glColor4f(r, g, b, a);
 
 1798 void TGLUtil::Color3fv(
const Float_t* rgb)
 
 1800    if (fgColorLockCount == 0) glColor3fv(rgb);
 
 1806 void TGLUtil::Color4fv(
const Float_t* rgba)
 
 1808    if (fgColorLockCount == 0) glColor4fv(rgba);
 
 1818 void TGLUtil::PointToViewport(Int_t& x, Int_t& y)
 
 1820    if (fgScreenScalingFactor != 1.0)
 
 1822       x = TMath::Nint(x * fgScreenScalingFactor);
 
 1823       y = TMath::Nint(y * fgScreenScalingFactor);
 
 1830 void TGLUtil::PointToViewport(Int_t& x, Int_t& y, Int_t& w, Int_t& h)
 
 1832    if (fgScreenScalingFactor != 1.0)
 
 1834       x = TMath::Nint(x * fgScreenScalingFactor);
 
 1835       y = TMath::Nint(y * fgScreenScalingFactor);
 
 1836       w = TMath::Nint(w * fgScreenScalingFactor);
 
 1837       h = TMath::Nint(h * fgScreenScalingFactor);
 
 1847 Float_t TGLUtil::GetScreenScalingFactor()
 
 1849    return fgScreenScalingFactor;
 
 1858 Float_t TGLUtil::GetPointLineScalingFactor()
 
 1860    return fgPointLineScalingFactor;
 
 1866 Int_t TGLUtil::GetPickingRadius()
 
 1868    return fgPickingRadius;
 
 1878 Float_t TGLUtil::GetPointSizeScale()
 
 1880    return fgPointSizeScale;
 
 1886 void TGLUtil::SetPointSizeScale(Float_t scale)
 
 1888    fgPointSizeScale = scale;
 
 1894 Float_t TGLUtil::GetLineWidthScale()
 
 1896    return fgLineWidthScale;
 
 1902 void TGLUtil::SetLineWidthScale(Float_t scale)
 
 1904    fgLineWidthScale = scale;
 
 1911 void TGLUtil::PointSize(Float_t point_size)
 
 1913    fgPointSize = point_size * fgPointSizeScale * fgPointLineScalingFactor;
 
 1914    glPointSize(fgPointSize);
 
 1921 void TGLUtil::LineWidth(Float_t line_width)
 
 1923    fgLineWidth = line_width * fgLineWidthScale * fgPointLineScalingFactor;
 
 1924    glLineWidth(fgLineWidth);
 
 1930 Float_t TGLUtil::PointSize()
 
 1938 Float_t TGLUtil::LineWidth()
 
 1947 void TGLUtil::BeginExtendPickRegion(Float_t scale)
 
 1951    glMatrixMode(GL_PROJECTION);
 
 1954    glGetFloatv(GL_PROJECTION_MATRIX, pm);
 
 1955    for (Int_t i=0; i<=12; i+=4) {
 
 1956       pm[i] *= scale; pm[i+1] *= scale;
 
 1959    glMatrixMode(GL_MODELVIEW);
 
 1962 void TGLUtil::EndExtendPickRegion()
 
 1966    glMatrixMode(GL_PROJECTION);
 
 1968    glMatrixMode(GL_MODELVIEW);
 
 1975 void TGLUtil::RenderPolyMarkers(
const TAttMarker& marker, Char_t transp,
 
 1976                                 Float_t* p, Int_t n,
 
 1977                                 Int_t pick_radius, Bool_t selection,
 
 1978                                 Bool_t sec_selection)
 
 1982    glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT | GL_LINE_BIT);
 
 1984    glDisable(GL_LIGHTING);
 
 1985    TGLUtil::ColorTransparency(marker.GetMarkerColor(), transp);
 
 1987    Int_t s = marker.GetMarkerStyle();
 
 1988    if (s == 2 || s == 3 || s == 5 || s == 28)
 
 1989       RenderCrosses(marker, p, n, sec_selection);
 
 1991       RenderPoints(marker, p, n, pick_radius, selection, sec_selection);
 
 2001 void TGLUtil::RenderPolyMarkers(
const TAttMarker &marker, 
const std::vector<Double_t> &points,
 
 2002                                 Double_t dX, Double_t dY, Double_t dZ)
 
 2004    const Int_t s = marker.GetMarkerStyle();
 
 2005    if (s == 2 || s == 3 || s == 5 || s == 28)
 
 2006       RenderCrosses(marker, points, dX, dY, dZ);
 
 2008       RenderPoints(marker, points);
 
 2015 void TGLUtil::RenderPoints(
const TAttMarker& marker,
 
 2016                            Float_t* op, Int_t n,
 
 2017                            Int_t pick_radius, Bool_t selection,
 
 2018                            Bool_t sec_selection)
 
 2020    Int_t   style = marker.GetMarkerStyle();
 
 2021    Float_t size  = 5*marker.GetMarkerSize();
 
 2022    if (style == 4 || style == 20 || style == 24)
 
 2024       glEnable(GL_POINT_SMOOTH);
 
 2025       if (style == 4 || style == 24) {
 
 2027          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 2028          glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
 
 2033       glDisable(GL_POINT_SMOOTH);
 
 2034       if      (style == 1) size = 1;
 
 2035       else if (style == 6) size = 2;
 
 2036       else if (style == 7) size = 3;
 
 2038    TGLUtil::PointSize(size);
 
 2041    Bool_t changePM = selection && PointSize() > pick_radius;
 
 2043       BeginExtendPickRegion((Float_t) pick_radius / PointSize());
 
 2049       for (Int_t i=0; i<n; ++i, p+=3)
 
 2060       glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
 
 2061       glVertexPointer(3, GL_FLOAT, 0, p);
 
 2062       glEnableClientState(GL_VERTEX_ARRAY);
 
 2066          const Int_t maxChunk = 8192;
 
 2067          while (nleft > maxChunk)
 
 2069             glDrawArrays(GL_POINTS, ndone, maxChunk);
 
 2073          glDrawArrays(GL_POINTS, ndone, nleft);
 
 2075       glPopClientAttrib();
 
 2079       EndExtendPickRegion();
 
 2086 void TGLUtil::RenderPoints(
const TAttMarker& marker, 
const std::vector<Double_t> &points)
 
 2088    const Int_t style = marker.GetMarkerStyle();
 
 2089    Float_t size = 5 * marker.GetMarkerSize();
 
 2091    if (style == 4 || style == 20 || style == 24)
 
 2093       glEnable(GL_POINT_SMOOTH);
 
 2094       if (style == 4 || style == 24) {
 
 2096          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 2097          glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
 
 2102       glDisable(GL_POINT_SMOOTH);
 
 2103       if      (style == 1) size = 1;
 
 2104       else if (style == 6) size = 2;
 
 2105       else if (style == 7) size = 3;
 
 2110    glVertexPointer(3, GL_DOUBLE, 0, &points[0]);
 
 2111    glEnableClientState(GL_VERTEX_ARRAY);
 
 2114    Int_t nleft = points.size() / 3;
 
 2116    const Int_t maxChunk = 8192;
 
 2117    while (nleft > maxChunk)
 
 2119       glDrawArrays(GL_POINTS, ndone, maxChunk);
 
 2125       glDrawArrays(GL_POINTS, ndone, nleft);
 
 2127    glDisableClientState(GL_VERTEX_ARRAY);
 
 2135 void TGLUtil::RenderCrosses(
const TAttMarker& marker,
 
 2136                             Float_t* op, Int_t n,
 
 2137                             Bool_t sec_selection)
 
 2139    if (marker.GetMarkerStyle() == 28)
 
 2142       glEnable(GL_LINE_SMOOTH);
 
 2143       TGLUtil::LineWidth(2);
 
 2147       glDisable(GL_LINE_SMOOTH);
 
 2148       TGLUtil::LineWidth(1);
 
 2152    const Float_t d = 2*marker.GetMarkerSize();
 
 2157       for (Int_t i=0; i<n; ++i, p+=3)
 
 2161          glVertex3f(p[0]-d, p[1],   p[2]);   glVertex3f(p[0]+d, p[1],   p[2]);
 
 2162          glVertex3f(p[0],   p[1]-d, p[2]);   glVertex3f(p[0],   p[1]+d, p[2]);
 
 2163          glVertex3f(p[0],   p[1],   p[2]-d); glVertex3f(p[0],   p[1],   p[2]+d);
 
 2171       for (Int_t i=0; i<n; ++i, p+=3)
 
 2173          glVertex3f(p[0]-d, p[1],   p[2]);   glVertex3f(p[0]+d, p[1],   p[2]);
 
 2174          glVertex3f(p[0],   p[1]-d, p[2]);   glVertex3f(p[0],   p[1]+d, p[2]);
 
 2175          glVertex3f(p[0],   p[1],   p[2]-d); glVertex3f(p[0],   p[1],   p[2]+d);
 
 2183       glDisable(GL_POINT_SMOOTH);
 
 2184       TGLUtil::PointSize(1);
 
 2186       glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
 
 2187       glVertexPointer(3, GL_FLOAT, 0, op);
 
 2188       glEnableClientState(GL_VERTEX_ARRAY);
 
 2192          const Int_t maxChunk = 8192;
 
 2193          while (nleft > maxChunk)
 
 2195             glDrawArrays(GL_POINTS, ndone, maxChunk);
 
 2199          glDrawArrays(GL_POINTS, ndone, nleft);
 
 2201       glPopClientAttrib();
 
 2209 void TGLUtil::RenderCrosses(
const TAttMarker& marker, 
const std::vector<Double_t> &points,
 
 2210                             Double_t dX, Double_t dY, Double_t dZ)
 
 2212    if (marker.GetMarkerStyle() == 28)
 
 2215       glEnable(GL_LINE_SMOOTH);
 
 2220       glDisable(GL_LINE_SMOOTH);
 
 2224    typedef std::vector<Double_t>::size_type size_type;
 
 2228    for (size_type i = 0; i < points.size(); i += 3) {
 
 2229       const Double_t *p = &points[i];
 
 2230       glVertex3f(p[0] - dX, p[1], p[2]); glVertex3f(p[0] + dX, p[1], p[2]);
 
 2231       glVertex3f(p[0], p[1] - dY, p[2]); glVertex3f(p[0], p[1] + dY, p[2]);
 
 2232       glVertex3f(p[0], p[1], p[2] - dZ); glVertex3f(p[0], p[1], p[2] + dZ);
 
 2237    if (marker.GetMarkerStyle() == 28) {
 
 2238       glDisable(GL_LINE_SMOOTH);
 
 2239       glDisable(GL_BLEND);
 
 2247 void TGLUtil::RenderPolyLine(
const TAttLine& aline, Char_t transp,
 
 2248                              Float_t* p, Int_t n,
 
 2249                              Int_t pick_radius, Bool_t selection)
 
 2253    BeginAttLine(aline, transp, pick_radius, selection);
 
 2256    glBegin(GL_LINE_STRIP);
 
 2257    for (Int_t i=0; i<n; ++i, tp+=3)
 
 2261    EndAttLine(pick_radius, selection);
 
 2267 void TGLUtil::BeginAttLine(
const TAttLine& aline, Char_t transp,
 
 2268                            Int_t pick_radius, Bool_t selection)
 
 2270    glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
 
 2272    glDisable(GL_LIGHTING);
 
 2273    TGLUtil::ColorTransparency(aline.GetLineColor(), transp);
 
 2274    TGLUtil::LineWidth(aline.GetLineWidth());
 
 2275    if (aline.GetLineStyle() > 1)
 
 2278       UShort_t pat = 0xffff;
 
 2279       switch (aline.GetLineStyle()) {
 
 2280          case 2:  pat = 0x3333; 
break;
 
 2281          case 3:  pat = 0x5555; 
break;
 
 2282          case 4:  pat = 0xf040; 
break;
 
 2283          case 5:  pat = 0xf4f4; 
break;
 
 2284          case 6:  pat = 0xf111; 
break;
 
 2285          case 7:  pat = 0xf0f0; 
break;
 
 2286          case 8:  pat = 0xff11; 
break;
 
 2287          case 9:  pat = 0x3fff; 
break;
 
 2288          case 10: pat = 0x08ff;  
break;
 
 2291       glLineStipple(1, pat);
 
 2292       glEnable(GL_LINE_STIPPLE);
 
 2296    if (selection && TGLUtil::LineWidth() > pick_radius)
 
 2297       BeginExtendPickRegion((Float_t) pick_radius / TGLUtil::LineWidth());
 
 2303 void TGLUtil::EndAttLine(Int_t pick_radius, Bool_t selection)
 
 2305    if (selection && TGLUtil::LineWidth() > pick_radius)
 
 2306      EndExtendPickRegion();
 
 2331 void TGLUtil::SetDrawColors(
const UChar_t rgbai[4])
 
 2335    Float_t rgba[4]     = {rgbai[0]/255.f, rgbai[1]/255.f, rgbai[2]/255.f, rgbai[3]/255.f};
 
 2336    Float_t ambient[4]  = {0.0, 0.0, 0.0, 1.0};
 
 2337    Float_t specular[4] = {0.6, 0.6, 0.6, 1.0};
 
 2338    Float_t emission[4] = {rgba[0]/4.f, rgba[1]/4.f, rgba[2]/4.f, rgba[3]};
 
 2341    glMaterialfv(GL_FRONT, GL_DIFFUSE, rgba);
 
 2342    glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
 
 2343    glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
 
 2344    glMaterialfv(GL_FRONT, GL_EMISSION, emission);
 
 2345    glMaterialf(GL_FRONT, GL_SHININESS, 60.0);
 
 2352 void TGLUtil::DrawSphere(
const TGLVertex3 & position, Double_t radius,
 
 2353                          const UChar_t rgba[4])
 
 2355    static TGLQuadric quad;
 
 2356    SetDrawColors(rgba);
 
 2358    glTranslated(position.X(), position.Y(), position.Z());
 
 2359    gluSphere(quad.Get(), radius, fgDrawQuality, fgDrawQuality);
 
 2367 void TGLUtil::DrawLine(
const TGLLine3 & line, ELineHeadShape head, Double_t size,
 
 2368                        const UChar_t rgba[4])
 
 2370    DrawLine(line.Start(), line.Vector(), head, size, rgba);
 
 2378 void TGLUtil::DrawLine(
const TGLVertex3 & start, 
const TGLVector3 & vector,
 
 2379                        ELineHeadShape head, Double_t size, 
const UChar_t rgba[4])
 
 2381    static TGLQuadric quad;
 
 2384    SetDrawColors(rgba);
 
 2386    TGLMatrix local(start, vector);
 
 2387    glMultMatrixd(local.CArr());
 
 2389    Double_t headHeight=0;
 
 2390    if (head == kLineHeadNone) {
 
 2392    } 
else if (head == kLineHeadArrow) {
 
 2393       headHeight = size*2.0;
 
 2394    } 
else if (head == kLineHeadBox) {
 
 2395       headHeight = size*1.4;
 
 2399    gluCylinder(quad.Get(), 0.25*size, 0.25*size, vector.Mag() - headHeight, fgDrawQuality, 1);
 
 2400    gluQuadricOrientation(quad.Get(), (GLenum)GLU_INSIDE);
 
 2401    gluDisk(quad.Get(), 0.0, 0.25*size, fgDrawQuality, 1);
 
 2403    glTranslated(0.0, 0.0, vector.Mag() - headHeight); 
 
 2405    if (head == kLineHeadNone) {
 
 2407       gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
 
 2408       gluDisk(quad.Get(), 0.0, size/4.0, fgDrawQuality, 1);
 
 2410    else if (head == kLineHeadArrow) {
 
 2412       gluDisk(quad.Get(), 0.0, size, fgDrawQuality, 1);
 
 2414       gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
 
 2415       gluCylinder(quad.Get(), size, 0.0, headHeight, fgDrawQuality, 1);
 
 2416    } 
else if (head == kLineHeadBox) {
 
 2421       gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
 
 2422       TGLBoundingBox box(TGLVertex3(-size*.7, -size*.7, 0.0),
 
 2423                          TGLVertex3(size*.7, size*.7, headHeight));
 
 2433 void TGLUtil::DrawRing(
const TGLVertex3 & center, 
const TGLVector3 & normal,
 
 2434                        Double_t radius, 
const UChar_t rgba[4])
 
 2436    static TGLQuadric quad;
 
 2440    TGLUtil::SetDrawColors(rgba);
 
 2442    Double_t outer = radius;
 
 2443    Double_t width = radius*0.05;
 
 2444    Double_t inner = outer - width;
 
 2448    TGLMatrix local(center, normal);
 
 2449    glMultMatrixd(local.CArr());
 
 2452    glTranslated(0.0, 0.0, -width/2.0);
 
 2455    gluCylinder(quad.Get(), inner, inner, width, fgDrawQuality, 1);
 
 2456    gluCylinder(quad.Get(), outer, outer, width, fgDrawQuality, 1);
 
 2459    gluQuadricOrientation(quad.Get(), (GLenum)GLU_INSIDE);
 
 2460    gluDisk(quad.Get(), inner, outer, fgDrawQuality, 1);
 
 2461    glTranslated(0.0, 0.0, width);
 
 2462    gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
 
 2463    gluDisk(quad.Get(), inner, outer, fgDrawQuality, 1);
 
 2474 void TGLUtil::DrawReferenceMarker(
const TGLCamera  & camera,
 
 2475                                   const TGLVertex3 & pos,
 
 2477                                   const UChar_t    * rgba)
 
 2479    static const UChar_t defColor[4] = { 250, 110, 0, 255 }; 
 
 2481    radius = camera.ViewportDeltaToWorld(pos, radius, radius).Mag();
 
 2482    DrawSphere(pos, radius, rgba ? rgba : defColor);
 
 2489 void TGLUtil::DrawSimpleAxes(
const TGLCamera      & camera,
 
 2490                              const TGLBoundingBox & bbox,
 
 2493    if (axesType == kAxesNone)
 
 2496    static const UChar_t axesColors[][4] = {
 
 2505    static const UChar_t xyz[][8] = {
 
 2506       {0x44, 0x44, 0x28, 0x10, 0x10, 0x28, 0x44, 0x44},
 
 2507       {0x10, 0x10, 0x10, 0x10, 0x10, 0x28, 0x44, 0x44},
 
 2508       {0x7c, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x7c}
 
 2512    TGLVector3 pixelVector = camera.ViewportDeltaToWorld(bbox.Center(), 1, 1);
 
 2513    Double_t   pixelSize   = pixelVector.Mag();
 
 2516    Double_t min[3] = { bbox.XMin(), bbox.YMin(), bbox.ZMin() };
 
 2517    Double_t max[3] = { bbox.XMax(), bbox.YMax(), bbox.ZMax() };
 
 2519    for (UInt_t i = 0; i < 3; i++) {
 
 2523       if (axesType == kAxesOrigin) {
 
 2525          start[(i+1)%3] = 0.0;
 
 2526          start[(i+2)%3] = 0.0;
 
 2529          start[(i+1)%3] = min[(i+1)%3];
 
 2530          start[(i+2)%3] = min[(i+2)%3];
 
 2532       vector[(i+1)%3] = 0.0;
 
 2533       vector[(i+2)%3] = 0.0;
 
 2543             vector[i] = min[i] - max[i];
 
 2545          DrawLine(start, vector, kLineHeadNone, pixelSize*2.5, axesColors[i*2]);
 
 2555             vector[i] = max[i] - min[i];
 
 2557          DrawLine(start, vector, kLineHeadNone, pixelSize*2.5, axesColors[i*2 + 1]);
 
 2562    if (axesType == kAxesOrigin) {
 
 2564       DrawSphere(TGLVertex3(0.0, 0.0, 0.0), pixelSize*2.0, fgWhite);
 
 2566       for (UInt_t j = 0; j < 3; j++) {
 
 2567          if (min[j] <= 0.0 && max[j] >= 0.0) {
 
 2570             zero[(j+1)%3] = min[(j+1)%3];
 
 2571             zero[(j+2)%3] = min[(j+2)%3];
 
 2572             DrawSphere(zero, pixelSize*2.0, axesColors[j*2 + 1]);
 
 2577    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
 2580    Double_t padPixels = 25.0;
 
 2582    glDisable(GL_LIGHTING);
 
 2583    for (UInt_t k = 0; k < 3; k++) {
 
 2584       SetDrawColors(axesColors[k*2+1]);
 
 2585       TGLVertex3 minPos, maxPos;
 
 2586       if (axesType == kAxesOrigin) {
 
 2587          minPos[(k+1)%3] = 0.0;
 
 2588          minPos[(k+2)%3] = 0.0;
 
 2590          minPos[(k+1)%3] = min[(k+1)%3];
 
 2591          minPos[(k+2)%3] = min[(k+2)%3];
 
 2597       TGLVector3 axis = maxPos - minPos;
 
 2598       TGLVector3 axisViewport = camera.WorldDeltaToViewport(minPos, axis);
 
 2602       if (axisViewport.Mag() < 1) {
 
 2606       minPos -= camera.ViewportDeltaToWorld(minPos, padPixels*axisViewport.X()/axisViewport.Mag(),
 
 2607                                                     padPixels*axisViewport.Y()/axisViewport.Mag());
 
 2608       axisViewport = camera.WorldDeltaToViewport(maxPos, -axis);
 
 2609       maxPos -= camera.ViewportDeltaToWorld(maxPos, padPixels*axisViewport.X()/axisViewport.Mag(),
 
 2610                                                     padPixels*axisViewport.Y()/axisViewport.Mag());
 
 2612       DrawNumber(Form(
"%.0f", min[k]), minPos, kTRUE); 
 
 2613       DrawNumber(Form(
"%.0f", max[k]), maxPos, kTRUE); 
 
 2616       TGLVertex3 namePos = maxPos -
 
 2617          camera.ViewportDeltaToWorld(maxPos, padPixels*axisViewport.X()/axisViewport.Mag(),
 
 2618                                      padPixels*axisViewport.Y()/axisViewport.Mag());
 
 2619       glRasterPos3dv(namePos.CArr());
 
 2620       glBitmap(8, 8, 0.0, 4.0, 0.0, 0.0, xyz[k]); 
 
 2629 void TGLUtil::DrawNumber(
const TString    & num,
 
 2630                          const TGLVertex3 & pos,
 
 2633    static const UChar_t digits[][8] = {
 
 2634       {0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38},
 
 2635       {0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x10, 0x10},
 
 2636       {0x7c, 0x44, 0x20, 0x18, 0x04, 0x04, 0x44, 0x38},
 
 2637       {0x38, 0x44, 0x04, 0x04, 0x18, 0x04, 0x44, 0x38},
 
 2638       {0x04, 0x04, 0x04, 0x04, 0x7c, 0x44, 0x44, 0x44},
 
 2639       {0x7c, 0x44, 0x04, 0x04, 0x7c, 0x40, 0x40, 0x7c},
 
 2640       {0x7c, 0x44, 0x44, 0x44, 0x7c, 0x40, 0x40, 0x7c},
 
 2641       {0x20, 0x20, 0x20, 0x10, 0x08, 0x04, 0x44, 0x7c},
 
 2642       {0x38, 0x44, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38},
 
 2643       {0x7c, 0x44, 0x04, 0x04, 0x7c, 0x44, 0x44, 0x7c},
 
 2644       {0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 
 2645       {0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00},
 
 2646       {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 
 
 2649    Double_t xOffset = 0, yOffset = 0;
 
 2652       xOffset = 3.5 * num.Length();
 
 2656    glRasterPos3dv(pos.CArr());
 
 2657    for (Ssiz_t i = 0, e = num.Length(); i < e; ++i) {
 
 2658       if (num[i] == 
'.') {
 
 2659          glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[10]);
 
 2660       } 
else if (num[i] == 
'-') {
 
 2661          glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[11]);
 
 2662       } 
else if (num[i] == 
' ') {
 
 2663          glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[12]);
 
 2664       } 
else if (num[i] >= 
'0' && num[i] <= 
'9') {
 
 2665          glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[num[i] - 
'0']);
 
 2677 TGLCapabilitySwitch::TGLCapabilitySwitch(Int_t what, Bool_t state) :
 
 2680    fState = glIsEnabled(fWhat);
 
 2681    fFlip  = (fState != state);
 
 2689 TGLCapabilitySwitch::~TGLCapabilitySwitch()
 
 2697 void TGLCapabilitySwitch::SetState(Bool_t s)
 
 2709 TGLCapabilityEnabler::TGLCapabilityEnabler(Int_t what, Bool_t state) :
 
 2712    fFlip = ! glIsEnabled(fWhat) && state;
 
 2720 TGLCapabilityEnabler::~TGLCapabilityEnabler()
 
 2729 TGLFloatHolder::TGLFloatHolder(Int_t what, Float_t state, 
void (*foo)(Float_t)) :
 
 2730       fWhat(what), fState(0), fFlip(kFALSE), fFoo(foo)
 
 2732       glGetFloatv(fWhat, &fState);
 
 2733       fFlip = (fState != state);
 
 2734       if (fFlip) fFoo(state);
 
 2739 TGLFloatHolder::~TGLFloatHolder()
 
 2741       if (fFlip) fFoo(fState);
 
 2748 TGLEnableGuard::TGLEnableGuard(Int_t cap)
 
 2751    glEnable(GLenum(fCap));
 
 2757 TGLEnableGuard::~TGLEnableGuard()
 
 2759    glDisable(GLenum(fCap));
 
 2765 TGLDisableGuard::TGLDisableGuard(Int_t cap)
 
 2768    glDisable(GLenum(fCap));
 
 2774 TGLDisableGuard::~TGLDisableGuard()
 
 2776    glEnable(GLenum(fCap));
 
 2783 ClassImp(TGLSelectionBuffer);
 
 2788 TGLSelectionBuffer::TGLSelectionBuffer()
 
 2789                         : fWidth(0), fHeight(0)
 
 2796 TGLSelectionBuffer::~TGLSelectionBuffer()
 
 2803 void TGLSelectionBuffer::ReadColorBuffer(Int_t w, Int_t h)
 
 2807    fBuffer.resize(w * h * 4);
 
 2808    glPixelStorei(GL_PACK_ALIGNMENT, 1);
 
 2809    glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, &fBuffer[0]);
 
 2815 void TGLSelectionBuffer::ReadColorBuffer(Int_t x, Int_t y, Int_t w, Int_t h)
 
 2819    fBuffer.resize(w * h * 4);
 
 2820    glPixelStorei(GL_PACK_ALIGNMENT, 1);
 
 2821    glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, &fBuffer[0]);
 
 2827 const UChar_t *TGLSelectionBuffer::GetPixelColor(Int_t px, Int_t py)
const 
 2834    if (UInt_t(px * fWidth * 4 + py * 4) > fBuffer.size())
 
 2837    return &fBuffer[px * fWidth * 4 + py * 4];
 
 2842 const Float_t gRedEmission[]    = {1.f, 0.f,  0.f, 1.f};
 
 2843 const Float_t gGreenEmission[]  = {0.f, 1.f,  0.f, 1.f};
 
 2844 const Float_t gBlueEmission[]   = {0.f, 0.f,  1.f, 1.f};
 
 2845 const Float_t gOrangeEmission[] = {1.f, 0.4f, 0.f, 1.f};
 
 2846 const Float_t gWhiteEmission[]  = {1.f, 1.f,  1.f, 1.f};
 
 2847 const Float_t gGrayEmission[]   = {0.3f,0.3f, 0.3f,1.f};
 
 2848 const Float_t gNullEmission[]   = {0.f, 0.f,  0.f, 1.f};
 
 2855    RGB_t gColorTriplets[] = {{{255, 0, 0}},
 
 2863    Bool_t operator < (
const RGB_t &lhs, 
const RGB_t &rhs)
 
 2865       if (lhs.fRGB[0] < rhs.fRGB[0])
 
 2867       else if (lhs.fRGB[0] > rhs.fRGB[0])
 
 2869       else if (lhs.fRGB[1] < rhs.fRGB[1])
 
 2871       else if (lhs.fRGB[1] > rhs.fRGB[1])
 
 2873       else if (lhs.fRGB[2] < rhs.fRGB[2])
 
 2879    typedef std::map<Int_t, RGB_t> ColorLookupTable_t;
 
 2880    typedef ColorLookupTable_t::const_iterator CLTCI_t;
 
 2882    ColorLookupTable_t gObjectIDToColor;
 
 2884    typedef std::map<RGB_t, Int_t> ObjectLookupTable_t;
 
 2885    typedef ObjectLookupTable_t::const_iterator OLTCI_t;
 
 2887    ObjectLookupTable_t gColorToObjectID;
 
 2892 void ObjectIDToColor(Int_t objectID, Bool_t highColor)
 
 2895       glColor3ub(objectID & 0xff, (objectID & 0xff00) >> 8, (objectID & 0xff0000) >> 16);
 
 2897       if (!gObjectIDToColor.size()) {
 
 2899          for (Int_t i = 0, 
id = 1; i < Int_t(
sizeof gColorTriplets / 
sizeof(RGB_t)); ++i, ++id)
 
 2900             gObjectIDToColor[
id] = gColorTriplets[i];
 
 2901          for (Int_t i = 0, 
id = 1; i < Int_t(
sizeof gColorTriplets / 
sizeof(RGB_t)); ++i, ++id)
 
 2902             gColorToObjectID[gColorTriplets[i]] = 
id;
 
 2905       CLTCI_t it = gObjectIDToColor.find(objectID);
 
 2907       if (it != gObjectIDToColor.end())
 
 2908          glColor3ub(it->second.fRGB[0], it->second.fRGB[1], it->second.fRGB[2]);
 
 2910          Error(
"ObjectIDToColor", 
"No color for such object ID: %d", objectID);
 
 2911          glColor3ub(0, 0, 0);
 
 2918 Int_t ColorToObjectID(
const UChar_t *pixel, Bool_t highColor)
 
 2921       return pixel[0] | (pixel[1] << 8) | (pixel[2] << 16);
 
 2923       if (!gObjectIDToColor.size())
 
 2926       RGB_t triplet = {{pixel[0], pixel[1], pixel[2]}};
 
 2927       OLTCI_t it = gColorToObjectID.find(triplet);
 
 2929       if (it != gColorToObjectID.end())
 
 2940 void DrawQuadOutline(
const TGLVertex3 &v1, 
const TGLVertex3 &v2,
 
 2941                      const TGLVertex3 &v3, 
const TGLVertex3 &v4)
 
 2943    glBegin(GL_LINE_LOOP);
 
 2944    glVertex3dv(v1.CArr());
 
 2945    glVertex3dv(v2.CArr());
 
 2946    glVertex3dv(v3.CArr());
 
 2947    glVertex3dv(v4.CArr());
 
 2954 void DrawQuadFilled(
const TGLVertex3 &v0, 
const TGLVertex3 &v1, 
const TGLVertex3 &v2,
 
 2955                      const TGLVertex3 &v3, 
const TGLVector3 &normal)
 
 2957    glBegin(GL_POLYGON);
 
 2958    glNormal3dv(normal.CArr());
 
 2959    glVertex3dv(v0.CArr());
 
 2960    glVertex3dv(v1.CArr());
 
 2961    glVertex3dv(v2.CArr());
 
 2962    glVertex3dv(v3.CArr());
 
 2969 void DrawQuadFilled(
const Double_t *v0, 
const Double_t *v1, 
const Double_t *v2, 
const Double_t *v3,
 
 2970                     const Double_t *normal)
 
 2973    glNormal3dv(normal);
 
 2984 void DrawSmoothFace(
const TGLVertex3 &v1, 
const TGLVertex3 &v2, 
const TGLVertex3 &v3,
 
 2985                   const TGLVector3 &norm1, 
const TGLVector3 &norm2, 
const TGLVector3 &norm3)
 
 2987    glBegin(GL_POLYGON);
 
 2988    glNormal3dv(norm1.CArr());
 
 2989    glVertex3dv(v1.CArr());
 
 2990    glNormal3dv(norm2.CArr());
 
 2991    glVertex3dv(v2.CArr());
 
 2992    glNormal3dv(norm3.CArr());
 
 2993    glVertex3dv(v3.CArr());
 
 2997 const Int_t    gBoxFrontQuads[][4] = {{0, 1, 2, 3}, {4, 0, 3, 5}, {4, 5, 6, 7}, {7, 6, 2, 1}};
 
 2998 const Double_t gBoxFrontNormals[][3] = {{-1., 0., 0.}, {0., -1., 0.}, {1., 0., 0.}, {0., 1., 0.}};
 
 2999 const Int_t    gBoxFrontPlanes[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 0}};
 
 3001 const Int_t    gBoxBackQuads[][4] = {{7, 1, 2, 6}, {4, 7, 6, 5}, {0, 4, 5, 3}, {0, 3, 2, 1}};
 
 3002 const Double_t gBoxBackNormals[][3] = {{0., -1., 0.}, {-1., 0., 0.}, {0., 1., 0.}, {1., 0., 0.}};
 
 3003 const Int_t    gBoxBackPlanes[][2] = {{0, 1}, {3, 0}, {2, 3}, {1, 2}};
 
 3008 void DrawBoxFront(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax,
 
 3009                   Double_t zMin, Double_t zMax, Int_t fp)
 
 3012       std::swap(zMax, zMin);
 
 3015    glBegin(GL_POLYGON);
 
 3016    glNormal3d(0., 0., -1.);
 
 3017    glVertex3d(xMax, yMin, zMin);
 
 3018    glVertex3d(xMin, yMin, zMin);
 
 3019    glVertex3d(xMin, yMax, zMin);
 
 3020    glVertex3d(xMax, yMax, zMin);
 
 3023    const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
 
 3024                               {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
 
 3025    const Int_t *verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
 
 3027    glBegin(GL_POLYGON);
 
 3028    glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][0]]);
 
 3029    glVertex3dv(box[verts[0]]);
 
 3030    glVertex3dv(box[verts[1]]);
 
 3031    glVertex3dv(box[verts[2]]);
 
 3032    glVertex3dv(box[verts[3]]);
 
 3035    verts = gBoxFrontQuads[gBoxFrontPlanes[fp][1]];
 
 3037    glBegin(GL_POLYGON);
 
 3038    glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][1]]);
 
 3039    glVertex3dv(box[verts[0]]);
 
 3040    glVertex3dv(box[verts[1]]);
 
 3041    glVertex3dv(box[verts[2]]);
 
 3042    glVertex3dv(box[verts[3]]);
 
 3046    glBegin(GL_POLYGON);
 
 3047    glNormal3d(0., 0., 1.);
 
 3048    glVertex3d(xMax, yMin, zMax);
 
 3049    glVertex3d(xMax, yMax, zMax);
 
 3050    glVertex3d(xMin, yMax, zMax);
 
 3051    glVertex3d(xMin, yMin, zMax);
 
 3058 void DrawTransparentBox(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax,
 
 3059                         Double_t zMin, Double_t zMax, Int_t fp)
 
 3062       std::swap(zMax, zMin);
 
 3068    glBegin(GL_POLYGON);
 
 3069    glNormal3d(0., 0., -1.);
 
 3070    glVertex3d(xMax, yMin, zMin);
 
 3071    glVertex3d(xMin, yMin, zMin);
 
 3072    glVertex3d(xMin, yMax, zMin);
 
 3073    glVertex3d(xMax, yMax, zMin);
 
 3076    const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
 
 3077                               {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
 
 3080    const Int_t *verts = gBoxBackQuads[gBoxBackPlanes[fp][0]];
 
 3082    glBegin(GL_POLYGON);
 
 3083    glNormal3dv(gBoxBackNormals[gBoxBackPlanes[fp][0]]);
 
 3084    glVertex3dv(box[verts[0]]);
 
 3085    glVertex3dv(box[verts[1]]);
 
 3086    glVertex3dv(box[verts[2]]);
 
 3087    glVertex3dv(box[verts[3]]);
 
 3090    verts = gBoxBackQuads[gBoxBackPlanes[fp][1]];
 
 3092    glBegin(GL_POLYGON);
 
 3093    glNormal3dv(gBoxBackNormals[gBoxBackPlanes[fp][1]]);
 
 3094    glVertex3dv(box[verts[0]]);
 
 3095    glVertex3dv(box[verts[1]]);
 
 3096    glVertex3dv(box[verts[2]]);
 
 3097    glVertex3dv(box[verts[3]]);
 
 3101    verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
 
 3103    glBegin(GL_POLYGON);
 
 3104    glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][0]]);
 
 3105    glVertex3dv(box[verts[0]]);
 
 3106    glVertex3dv(box[verts[1]]);
 
 3107    glVertex3dv(box[verts[2]]);
 
 3108    glVertex3dv(box[verts[3]]);
 
 3111    verts = gBoxFrontQuads[gBoxFrontPlanes[fp][1]];
 
 3113    glBegin(GL_POLYGON);
 
 3114    glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][1]]);
 
 3115    glVertex3dv(box[verts[0]]);
 
 3116    glVertex3dv(box[verts[1]]);
 
 3117    glVertex3dv(box[verts[2]]);
 
 3118    glVertex3dv(box[verts[3]]);
 
 3122    glBegin(GL_POLYGON);
 
 3123    glNormal3d(0., 0., 1.);
 
 3124    glVertex3d(xMax, yMin, zMax);
 
 3125    glVertex3d(xMax, yMax, zMax);
 
 3126    glVertex3d(xMin, yMax, zMax);
 
 3127    glVertex3d(xMin, yMin, zMax);
 
 3135 void DrawBoxFrontTextured(Double_t xMin, Double_t xMax, Double_t yMin,
 
 3136                            Double_t yMax, Double_t zMin, Double_t zMax,
 
 3137                            Double_t texMin, Double_t texMax, Int_t fp)
 
 3140       std::swap(zMax, zMin);
 
 3141       std::swap(texMax, texMin);
 
 3145    glBegin(GL_POLYGON);
 
 3146    glNormal3d(0., 0., 1.);
 
 3147    glTexCoord1d(texMax);
 
 3148    glVertex3d(xMax, yMin, zMax);
 
 3149    glVertex3d(xMax, yMax, zMax);
 
 3150    glVertex3d(xMin, yMax, zMax);
 
 3151    glVertex3d(xMin, yMin, zMax);
 
 3154    glBegin(GL_POLYGON);
 
 3155    glTexCoord1d(texMin);
 
 3156    glNormal3d(0., 0., -1.);
 
 3157    glVertex3d(xMax, yMin, zMin);
 
 3158    glVertex3d(xMin, yMin, zMin);
 
 3159    glVertex3d(xMin, yMax, zMin);
 
 3160    glVertex3d(xMax, yMax, zMin);
 
 3163    const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
 
 3164                               {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
 
 3166    const Double_t tex[] = {texMax, texMax, texMin, texMin, texMax, texMin, texMin, texMax};
 
 3167    const Int_t *verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
 
 3169    glBegin(GL_POLYGON);
 
 3170    glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][0]]);
 
 3171    glTexCoord1d(tex[verts[0]]);
 
 3172    glVertex3dv(box[verts[0]]);
 
 3173    glTexCoord1d(tex[verts[1]]);
 
 3174    glVertex3dv(box[verts[1]]);
 
 3175    glTexCoord1d(tex[verts[2]]);
 
 3176    glVertex3dv(box[verts[2]]);
 
 3177    glTexCoord1d(tex[verts[3]]);
 
 3178    glVertex3dv(box[verts[3]]);
 
 3181    verts = gBoxFrontQuads[gBoxFrontPlanes[fp][1]];
 
 3183    glBegin(GL_POLYGON);
 
 3184    glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][1]]);
 
 3185    glTexCoord1d(tex[verts[0]]);
 
 3186    glVertex3dv(box[verts[0]]);
 
 3187    glTexCoord1d(tex[verts[1]]);
 
 3188    glVertex3dv(box[verts[1]]);
 
 3189    glTexCoord1d(tex[verts[2]]);
 
 3190    glVertex3dv(box[verts[2]]);
 
 3191    glTexCoord1d(tex[verts[3]]);
 
 3192    glVertex3dv(box[verts[3]]);
 
 3198 void DrawBoxWithGradientFill(Double_t y1, Double_t y2, Double_t x1, Double_t x2,
 
 3199                              const Double_t *rgba1, 
const Double_t *rgba2)
 
 3201    assert(rgba1 != 0 && 
"DrawBoxWithGradientFill, parameter 'rgba1' is null");
 
 3202    assert(rgba2 != 0 && 
"DrawBoxWithGradientFill, parameter 'rgba2' is null");
 
 3204    glBegin(GL_POLYGON);
 
 3218 void DrawQuadStripWithRadialGradientFill(
unsigned nPoints, 
const Double_t *inner, 
const Double_t *innerRGBA,
 
 3219                                          const Double_t *outer, 
const Double_t *outerRGBA)
 
 3221    assert(nPoints != 0 &&
 
 3222           "DrawQuadStripWithRadialGradientFill, invalid number of points");
 
 3223    assert(inner != 0 &&
 
 3224           "DrawQuadStripWithRadialGradientFill, parameter 'inner' is null");
 
 3225    assert(innerRGBA != 0 &&
 
 3226           "DrawQuadStripWithRadialGradientFill, parameter 'innerRGBA' is null");
 
 3227    assert(outer != 0 &&
 
 3228           "DrawQuadStripWithRadialGradientFill, parameter 'outer' is null");
 
 3229    assert(outerRGBA != 0 &&
 
 3230           "DrawQuadStripWithRadialGradientFill, parameter 'outerRGBA' is null");
 
 3232    glBegin(GL_QUAD_STRIP);
 
 3233    for (UInt_t j = 0; j < nPoints; ++j) {
 
 3234       glColor4dv(innerRGBA);
 
 3235       glVertex2dv(inner + j * 2);
 
 3236       glColor4dv(outerRGBA);
 
 3237       glVertex2dv(outer + j * 2);
 
 3245 void DrawCylinder(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin,
 
 3246                   Double_t yMax, Double_t zMin, Double_t zMax)
 
 3248    GLUquadric *quad = quadric->Get();
 
 3252          std::swap(zMin, zMax);
 
 3253       const Double_t xCenter = xMin + (xMax - xMin) / 2;
 
 3254       const Double_t yCenter = yMin + (yMax - yMin) / 2;
 
 3255       const Double_t radius = TMath::Min((xMax - xMin) / 2, (yMax - yMin) / 2);
 
 3258       glTranslated(xCenter, yCenter, zMin);
 
 3259       gluCylinder(quad, radius, radius, zMax - zMin, 40, 1);
 
 3262       glTranslated(xCenter, yCenter, zMax);
 
 3263       gluDisk(quad, 0., radius, 40, 1);
 
 3266       glTranslated(xCenter, yCenter, zMin);
 
 3267       glRotated(180., 0., 1., 0.);
 
 3268       gluDisk(quad, 0., radius, 40, 1);
 
 3276 void DrawSphere(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin,
 
 3277                   Double_t yMax, Double_t zMin, Double_t zMax)
 
 3279    GLUquadric *quad = quadric->Get();
 
 3282       const Double_t xCenter = xMin + (xMax - xMin) / 2;
 
 3283       const Double_t yCenter = yMin + (yMax - yMin) / 2;
 
 3284       const Double_t zCenter = zMin + (zMax - zMin) / 2;
 
 3286       const Double_t radius = TMath::Min((zMax - zMin) / 2,
 
 3287                                           TMath::Min((xMax - xMin) / 2, (yMax - yMin) / 2));
 
 3290       glTranslated(xCenter, yCenter, zCenter);
 
 3291       gluSphere(quad, radius, 10, 10);
 
 3299 void DrawError(Double_t xMin, Double_t xMax, Double_t yMin,
 
 3300                Double_t yMax, Double_t zMin, Double_t zMax)
 
 3302    const Double_t xWid = xMax - xMin;
 
 3303    const Double_t yWid = yMax - yMin;
 
 3306    glVertex3d(xMin + xWid / 2, yMin + yWid / 2, zMin);
 
 3307    glVertex3d(xMin + xWid / 2, yMin + yWid / 2, zMax);
 
 3311    glVertex3d(xMin + xWid / 2, yMin, zMin);
 
 3312    glVertex3d(xMin + xWid / 2, yMax, zMin);
 
 3316    glVertex3d(xMin, yMin + yWid / 2, zMin);
 
 3317    glVertex3d(xMax, yMin + yWid / 2, zMin);
 
 3321 void CylindricalNormal(
const Double_t *v, Double_t *normal)
 
 3323    const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1]);
 
 3325       normal[0] = v[0] / n;
 
 3326       normal[1] = v[1] / n;
 
 3335 void CylindricalNormalInv(
const Double_t *v, Double_t *normal)
 
 3337    const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1]);
 
 3339       normal[0] = -v[0] / n;
 
 3340       normal[1] = -v[1] / n;
 
 3349 void DrawTrapezoid(
const Double_t ver[][2], Double_t zMin, Double_t zMax, Bool_t color)
 
 3354       std::swap(zMin, zMax);
 
 3356    glBegin(GL_POLYGON);
 
 3357    glNormal3d(0., 0., 1.);
 
 3358    glVertex3d(ver[0][0], ver[0][1], zMax);
 
 3359    glVertex3d(ver[1][0], ver[1][1], zMax);
 
 3360    glVertex3d(ver[2][0], ver[2][1], zMax);
 
 3361    glVertex3d(ver[3][0], ver[3][1], zMax);
 
 3364    glBegin(GL_POLYGON);
 
 3365    glNormal3d(0., 0., -1.);
 
 3366    glVertex3d(ver[0][0], ver[0][1], zMin);
 
 3367    glVertex3d(ver[3][0], ver[3][1], zMin);
 
 3368    glVertex3d(ver[2][0], ver[2][1], zMin);
 
 3369    glVertex3d(ver[1][0], ver[1][1], zMin);
 
 3373    Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
 
 3374                               {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
 
 3375                               {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
 
 3376                               {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
 
 3377    Double_t normal[3] = {0.};
 
 3378    glBegin(GL_POLYGON);
 
 3379    CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glVertex3dv(trapezoid[1]);
 
 3380    CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glVertex3dv(trapezoid[2]);
 
 3381    CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glVertex3dv(trapezoid[6]);
 
 3382    CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glVertex3dv(trapezoid[5]);
 
 3385    glBegin(GL_POLYGON);
 
 3386    CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glVertex3dv(trapezoid[0]);
 
 3387    CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glVertex3dv(trapezoid[4]);
 
 3388    CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glVertex3dv(trapezoid[7]);
 
 3389    CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glVertex3dv(trapezoid[3]);
 
 3392    glBegin(GL_POLYGON);
 
 3394       TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
 
 3395       glNormal3dv(normal);
 
 3397    glVertex3dv(trapezoid[0]);
 
 3398    glVertex3dv(trapezoid[1]);
 
 3399    glVertex3dv(trapezoid[5]);
 
 3400    glVertex3dv(trapezoid[4]);
 
 3403    glBegin(GL_POLYGON);
 
 3405       TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
 
 3406       glNormal3dv(normal);
 
 3408    glVertex3dv(trapezoid[3]);
 
 3409    glVertex3dv(trapezoid[7]);
 
 3410    glVertex3dv(trapezoid[6]);
 
 3411    glVertex3dv(trapezoid[2]);
 
 3419 void DrawTrapezoidTextured(
const Double_t ver[][2], Double_t zMin, Double_t zMax,
 
 3420                            Double_t texMin, Double_t texMax)
 
 3423       std::swap(zMin, zMax);
 
 3424       std::swap(texMin, texMax);
 
 3428    glBegin(GL_POLYGON);
 
 3429    glNormal3d(0., 0., 1.);
 
 3430    glTexCoord1d(texMax);
 
 3431    glVertex3d(ver[0][0], ver[0][1], zMax);
 
 3432    glVertex3d(ver[1][0], ver[1][1], zMax);
 
 3433    glVertex3d(ver[2][0], ver[2][1], zMax);
 
 3434    glVertex3d(ver[3][0], ver[3][1], zMax);
 
 3437    glBegin(GL_POLYGON);
 
 3438    glNormal3d(0., 0., -1.);
 
 3439    glTexCoord1d(texMin);
 
 3440    glVertex3d(ver[0][0], ver[0][1], zMin);
 
 3441    glVertex3d(ver[3][0], ver[3][1], zMin);
 
 3442    glVertex3d(ver[2][0], ver[2][1], zMin);
 
 3443    glVertex3d(ver[1][0], ver[1][1], zMin);
 
 3447    Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
 
 3448                               {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
 
 3449                               {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
 
 3450                               {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
 
 3451    Double_t normal[3] = {0.};
 
 3452    glBegin(GL_POLYGON);
 
 3453    CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[1]);
 
 3454    CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[2]);
 
 3455    CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[6]);
 
 3456    CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[5]);
 
 3459    glBegin(GL_POLYGON);
 
 3460    CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[0]);
 
 3461    CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[4]);
 
 3462    CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[7]);
 
 3463    CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[3]);
 
 3466    glBegin(GL_POLYGON);
 
 3467    TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
 
 3468    glNormal3dv(normal);
 
 3469    glTexCoord1d(texMin);
 
 3470    glVertex3dv(trapezoid[0]);
 
 3471    glTexCoord1d(texMin);
 
 3472    glVertex3dv(trapezoid[1]);
 
 3473    glTexCoord1d(texMax);
 
 3474    glVertex3dv(trapezoid[5]);
 
 3475    glTexCoord1d(texMax);
 
 3476    glVertex3dv(trapezoid[4]);
 
 3479    glBegin(GL_POLYGON);
 
 3480    TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
 
 3481    glNormal3dv(normal);
 
 3482    glTexCoord1d(texMin);
 
 3483    glVertex3dv(trapezoid[3]);
 
 3484    glTexCoord1d(texMax);
 
 3485    glVertex3dv(trapezoid[7]);
 
 3486    glTexCoord1d(texMax);
 
 3487    glVertex3dv(trapezoid[6]);
 
 3488    glTexCoord1d(texMin);
 
 3489    glVertex3dv(trapezoid[2]);
 
 3496 void DrawTrapezoidTextured2(
const Double_t ver[][2], Double_t zMin, Double_t zMax,
 
 3497                               Double_t texMin, Double_t texMax)
 
 3500       std::swap(zMin, zMax);
 
 3502    const Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
 
 3503                                     {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
 
 3504                                     {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
 
 3505                                     {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
 
 3506    const Double_t tex[] = {texMin, texMax, texMax, texMin, texMin, texMax, texMax, texMin};
 
 3508    glBegin(GL_POLYGON);
 
 3509    glNormal3d(0., 0., 1.);
 
 3510    glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
 
 3511    glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
 
 3512    glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
 
 3513    glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
 
 3516    glBegin(GL_POLYGON);
 
 3517    glNormal3d(0., 0., -1.);
 
 3518    glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
 
 3519    glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
 
 3520    glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
 
 3521    glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
 
 3524    glBegin(GL_POLYGON);
 
 3525    Double_t normal[3] = {};
 
 3526    CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
 
 3527    CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
 
 3528    CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
 
 3529    CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
 
 3532    glBegin(GL_POLYGON);
 
 3533    CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
 
 3534    CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
 
 3535    CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
 
 3536    CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
 
 3539    glBegin(GL_POLYGON);
 
 3540    TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
 
 3541    glNormal3dv(normal);
 
 3542    glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
 
 3543    glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
 
 3544    glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
 
 3545    glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
 
 3548    glBegin(GL_POLYGON);
 
 3549    TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
 
 3550    glNormal3dv(normal);
 
 3551    glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
 
 3552    glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
 
 3553    glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
 
 3554    glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
 
 3560 void SphericalNormal(
const Double_t *v, Double_t *normal)
 
 3562    const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
 
 3564       normal[0] = v[0] / n;
 
 3565       normal[1] = v[1] / n;
 
 3566       normal[2] = v[2] / n;
 
 3576 void SphericalNormalInv(
const Double_t *v, Double_t *normal)
 
 3578    const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
 
 3580       normal[0] = -v[0] / n;
 
 3581       normal[1] = -v[1] / n;
 
 3582       normal[2] = -v[2] / n;
 
 3592 void DrawTrapezoid(
const Double_t ver[][3])
 
 3594    Double_t normal[3] = {0.};
 
 3596    glBegin(GL_POLYGON);
 
 3597    TMath::Normal2Plane(ver[1], ver[2], ver[3], normal);
 
 3598    glNormal3dv(normal);
 
 3599    glVertex3dv(ver[0]);
 
 3600    glVertex3dv(ver[1]);
 
 3601    glVertex3dv(ver[2]);
 
 3602    glVertex3dv(ver[3]);
 
 3605    glBegin(GL_POLYGON);
 
 3606    TMath::Normal2Plane(ver[4], ver[7], ver[6], normal);
 
 3607    glNormal3dv(normal);
 
 3608    glVertex3dv(ver[4]);
 
 3609    glVertex3dv(ver[7]);
 
 3610    glVertex3dv(ver[6]);
 
 3611    glVertex3dv(ver[5]);
 
 3615    glBegin(GL_POLYGON);
 
 3616    TMath::Normal2Plane(ver[0], ver[3], ver[7], normal);
 
 3617    glNormal3dv(normal);
 
 3618    glVertex3dv(ver[0]);
 
 3619    glVertex3dv(ver[3]);
 
 3620    glVertex3dv(ver[7]);
 
 3621    glVertex3dv(ver[4]);
 
 3624    glBegin(GL_POLYGON);
 
 3625    SphericalNormal(ver[3], normal), glNormal3dv(normal), glVertex3dv(ver[3]);
 
 3626    SphericalNormal(ver[2], normal), glNormal3dv(normal), glVertex3dv(ver[2]);
 
 3627    SphericalNormal(ver[6], normal), glNormal3dv(normal), glVertex3dv(ver[6]);
 
 3628    SphericalNormal(ver[7], normal), glNormal3dv(normal), glVertex3dv(ver[7]);
 
 3631    glBegin(GL_POLYGON);
 
 3632    TMath::Normal2Plane(ver[5], ver[6], ver[2], normal);
 
 3633    glNormal3dv(normal);
 
 3634    glVertex3dv(ver[5]);
 
 3635    glVertex3dv(ver[6]);
 
 3636    glVertex3dv(ver[2]);
 
 3637    glVertex3dv(ver[1]);
 
 3640    glBegin(GL_POLYGON);
 
 3641    SphericalNormalInv(ver[0], normal), glNormal3dv(normal), glVertex3dv(ver[0]);
 
 3642    SphericalNormalInv(ver[4], normal), glNormal3dv(normal), glVertex3dv(ver[4]);
 
 3643    SphericalNormalInv(ver[5], normal), glNormal3dv(normal), glVertex3dv(ver[5]);
 
 3644    SphericalNormalInv(ver[1], normal), glNormal3dv(normal), glVertex3dv(ver[1]);
 
 3650 void DrawTrapezoidTextured(
const Double_t ver[][3], Double_t texMin, Double_t texMax)
 
 3652    Double_t normal[3] = {};
 
 3653    if (texMin > texMax)
 
 3654       std::swap(texMin, texMax);
 
 3656    const Double_t tex[] = {texMin, texMin, texMax, texMax, texMin, texMin, texMax, texMax};
 
 3657    glBegin(GL_POLYGON);
 
 3658    TMath::Normal2Plane(ver[0], ver[1], ver[2], normal);
 
 3659    glNormal3dv(normal);
 
 3660    glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
 
 3661    glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
 
 3662    glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
 
 3663    glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
 
 3665    glBegin(GL_POLYGON);
 
 3666    TMath::Normal2Plane(ver[4], ver[7], ver[6], normal);
 
 3667    glNormal3dv(normal);
 
 3668    glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
 
 3669    glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
 
 3670    glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
 
 3671    glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
 
 3673    glBegin(GL_POLYGON);
 
 3674    TMath::Normal2Plane(ver[0], ver[3], ver[7], normal);
 
 3675    glNormal3dv(normal);
 
 3676    glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
 
 3677    glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
 
 3678    glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
 
 3679    glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
 
 3681    glBegin(GL_POLYGON);
 
 3682    SphericalNormal(ver[3], normal), glNormal3dv(normal), glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
 
 3683    SphericalNormal(ver[2], normal), glNormal3dv(normal), glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
 
 3684    SphericalNormal(ver[6], normal), glNormal3dv(normal), glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
 
 3685    SphericalNormal(ver[7], normal), glNormal3dv(normal), glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
 
 3687    glBegin(GL_POLYGON);
 
 3688    TMath::Normal2Plane(ver[5], ver[6], ver[2], normal);
 
 3689    glNormal3dv(normal);
 
 3690    glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
 
 3691    glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
 
 3692    glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
 
 3693    glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
 
 3695    glBegin(GL_POLYGON);
 
 3696    SphericalNormalInv(ver[0], normal), glNormal3dv(normal), glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
 
 3697    SphericalNormalInv(ver[4], normal), glNormal3dv(normal), glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
 
 3698    SphericalNormalInv(ver[5], normal), glNormal3dv(normal), glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
 
 3699    SphericalNormalInv(ver[1], normal), glNormal3dv(normal), glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
 
 3704 void Draw2DAxis(TAxis *axis, Double_t xMin, Double_t yMin, Double_t xMax, Double_t yMax,
 
 3705                Double_t min, Double_t max, Bool_t log, Bool_t z = kFALSE)
 
 3711    if (xMin > xMax || z) option += 
"SDH=+";
 
 3712    else option += 
"SDH=-";
 
 3714    if (log) option += 
'G';
 
 3716    Int_t nDiv = axis->GetNdivisions();
 
 3724    axisPainter.SetLineWidth(1);
 
 3726    static const Double_t zero = 0.001;
 
 3728    if (TMath::Abs(xMax - xMin) >= zero || TMath::Abs(yMax - yMin) >= zero) {
 
 3729       axisPainter.ImportAxisAttributes(axis);
 
 3730       axisPainter.SetLabelOffset(axis->GetLabelOffset() + axis->GetTickLength());
 
 3733          min = TMath::Power(10, min);
 
 3734          max = TMath::Power(10, max);
 
 3737       if (axis->GetTimeDisplay()) {
 
 3740          if (!strlen(axis->GetTimeFormatOnly()))
 
 3741             axisPainter.SetTimeFormat(axis->ChooseTimeFormat(max - min));
 
 3743             axisPainter.SetTimeFormat(axis->GetTimeFormat());
 
 3746       axisPainter.SetOption(option.c_str());
 
 3747       axisPainter.PaintAxis(xMin, yMin, xMax, yMax, min, max, nDiv, option.c_str());
 
 3751 const Int_t gFramePoints[][2] = {{3, 1}, {0, 2}, {1, 3}, {2, 0}};
 
 3753 const Int_t gAxisType[][2]    = {{1, 0}, {0, 1}, {1, 0}, {0, 1}};
 
 3760 void DrawAxes(Int_t fp, 
const Int_t *vp, 
const TGLVertex3 *box, 
const TGLPlotCoordinates *coord,
 
 3761                TAxis *xAxis, TAxis *yAxis, TAxis *zAxis)
 
 3763    const Int_t left  = gFramePoints[fp][0];
 
 3764    const Int_t right = gFramePoints[fp][1];
 
 3765    const Double_t xLeft = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
 
 3766                                              + box[left].X() - vp[0]));
 
 3767    const Double_t yLeft = gPad->AbsPixeltoY(Int_t(vp[3] - box[left].Y()
 
 3768                                              + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
 
 3769                                              * gPad->GetWh() + vp[1]));
 
 3770    const Double_t xMid = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
 
 3771                                              + box[fp].X()  - vp[0]));
 
 3772    const Double_t yMid = gPad->AbsPixeltoY(Int_t(vp[3] - box[fp].Y()
 
 3773                                              + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
 
 3774                                              * gPad->GetWh() + vp[1]));
 
 3775    const Double_t xRight = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC()
 
 3776                                              * gPad->GetWw() + box[right].X() - vp[0]));
 
 3777    const Double_t yRight = gPad->AbsPixeltoY(Int_t(vp[3] - box[right].Y()
 
 3778                                              + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
 
 3779                                              * gPad->GetWh() + vp[1]));
 
 3780    const Double_t points[][2] = {{coord->GetXRange().first,  coord->GetYRange().first },
 
 3781                                  {coord->GetXRange().second, coord->GetYRange().first },
 
 3782                                  {coord->GetXRange().second, coord->GetYRange().second},
 
 3783                                  {coord->GetXRange().first,  coord->GetYRange().second}};
 
 3784    const Int_t    leftType      = gAxisType[fp][0];
 
 3785    const Int_t    rightType     = gAxisType[fp][1];
 
 3786    const Double_t leftLabel     = points[left][leftType];
 
 3787    const Double_t leftMidLabel  = points[fp][leftType];
 
 3788    const Double_t rightMidLabel = points[fp][rightType];
 
 3789    const Double_t rightLabel    = points[right][rightType];
 
 3791    if (xLeft - xMid || yLeft - yMid) {
 
 3792       TAxis *axis = leftType ? yAxis : xAxis;
 
 3793       if (leftLabel < leftMidLabel)
 
 3794          Draw2DAxis(axis, xLeft, yLeft, xMid, yMid, leftLabel, leftMidLabel,
 
 3795                      leftType ? coord->GetYLog() : coord->GetXLog());
 
 3797          Draw2DAxis(axis, xMid, yMid, xLeft, yLeft, leftMidLabel, leftLabel,
 
 3798                      leftType ? coord->GetYLog() : coord->GetXLog());
 
 3801    if (xRight - xMid || yRight - yMid) {
 
 3802       TAxis *axis = rightType ? yAxis : xAxis;
 
 3804       if (rightMidLabel < rightLabel)
 
 3805          Draw2DAxis(axis, xMid, yMid, xRight, yRight, rightMidLabel, rightLabel,
 
 3806                      rightType ? coord->GetYLog() : coord->GetXLog());
 
 3808          Draw2DAxis(axis, xRight, yRight, xMid, yMid, rightLabel, rightMidLabel,
 
 3809                      rightType ? coord->GetYLog() : coord->GetXLog());
 
 3812    const Double_t xUp = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
 
 3813                                           + box[left + 4].X() - vp[0]));
 
 3814    const Double_t yUp = gPad->AbsPixeltoY(Int_t(vp[3] - box[left + 4].Y()
 
 3815                                           + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
 
 3816                                           * gPad->GetWh() + vp[1]));
 
 3817    Draw2DAxis(zAxis, xLeft, yLeft, xUp, yUp, coord->GetZRange().first,
 
 3818                coord->GetZRange().second, coord->GetZLog(), kTRUE);
 
 3821 void SetZLevels(TAxis *zAxis, Double_t zMin, Double_t zMax,
 
 3822                   Double_t zScale, std::vector<Double_t> &zLevels)
 
 3824    Int_t nDiv = zAxis->GetNdivisions() % 100;
 
 3826    Double_t binLow = 0., binHigh = 0., binWidth = 0.;
 
 3827    THLimitsFinder::Optimize(zMin, zMax, nDiv, binLow, binHigh, nBins, binWidth, 
" ");
 
 3828    zLevels.resize(nBins + 1);
 
 3830    for (Int_t i = 0; i < nBins + 1; ++i)
 
 3831       zLevels[i] = (binLow + i * binWidth) * zScale;
 
 3837 void DrawFaceTextured(
const TGLVertex3 &v1, 
const TGLVertex3 &v2, 
const TGLVertex3 &v3,
 
 3838                         Double_t t1, Double_t t2, Double_t t3, 
const TGLVector3 &norm1,
 
 3839                         const TGLVector3 &norm2, 
const TGLVector3 &norm3)
 
 3841    glBegin(GL_POLYGON);
 
 3842    glNormal3dv(norm1.CArr());
 
 3844    glVertex3dv(v1.CArr());
 
 3845    glNormal3dv(norm2.CArr());
 
 3847    glVertex3dv(v2.CArr());
 
 3848    glNormal3dv(norm3.CArr());
 
 3850    glVertex3dv(v3.CArr());
 
 3857 void DrawFaceTextured(
const TGLVertex3 &v1, 
const TGLVertex3 &v2, 
const TGLVertex3 &v3,
 
 3858                         Double_t t1, Double_t t2, Double_t t3, Double_t z,
 
 3859                         const TGLVector3 &normal)
 
 3861    glBegin(GL_POLYGON);
 
 3862    glNormal3dv(normal.CArr());
 
 3864    glVertex3d(v1.X(), v1.Y(), z);
 
 3866    glVertex3d(v2.X(), v2.Y(), z);
 
 3868    glVertex3d(v3.X(), v3.Y(), z);
 
 3878 void GetColor(Float_t v, Float_t vmin, Float_t vmax, Int_t type, Float_t *rgba)
 
 3882    Float_t c1[3] = {}, c2[3] = {}, c3[3] = {};
 
 3899    if (v < (vmin + 0.25 * dv)) {
 
 3901       rgba[1] = 4 * (v - vmin) / dv;
 
 3903    } 
else if (v < (vmin + 0.5 * dv)) {
 
 3906       rgba[2] = 1 + 4 * (vmin + 0.25 * dv - v) / dv;
 
 3907    } 
else if (v < (vmin + 0.75 * dv)) {
 
 3908       rgba[0] = 4 * (v - vmin - 0.5 * dv) / dv;
 
 3913       rgba[1] = 1 + 4 * (vmin + 0.75 * dv - v) / dv;
 
 3918       rgba[0] = (v - vmin) / dv;
 
 3920       rgba[2] = (vmax - v) / dv;
 
 3923       rgba[0] = (v - vmin) / dv;
 
 3928       if (v < (vmin + dv / 6.0)) {
 
 3930          rgba[1] = 6 * (v - vmin) / dv;
 
 3932       } 
else if (v < (vmin + 2.0 * dv / 6.0)) {
 
 3933          rgba[0] = 1 + 6 * (vmin + dv / 6.0 - v) / dv;
 
 3936       } 
else if (v < (vmin + 3.0 * dv / 6.0)) {
 
 3939          rgba[2] = 6 * (v - vmin - 2.0 * dv / 6.0) / dv;
 
 3940       } 
else if (v < (vmin + 4.0 * dv / 6.0)) {
 
 3942          rgba[1] = 1 + 6 * (vmin + 3.0 * dv / 6.0 - v) / dv;
 
 3944       } 
else if (v < (vmin + 5.0 * dv / 6.0)) {
 
 3945          rgba[0] = 6 * (v - vmin - 4.0 * dv / 6.0) / dv;
 
 3951          rgba[2] = 1 + 6 * (vmin + 5.0 * dv / 6.0 - v) / dv;
 
 3955       rgba[0] = (v - vmin) / (vmax - vmin);
 
 3960       rgba[0] = (v - vmin) / (vmax - vmin);
 
 3961       rgba[1] = (vmax - v) / (vmax - vmin);
 
 3965       if (v < (vmin + 0.25 * dv)) {
 
 3967          rgba[1] = 4 * (v - vmin) / dv;
 
 3968          rgba[2] = 1 - rgba[1];
 
 3969       } 
else if (v < (vmin + 0.5 * dv)) {
 
 3970          rgba[0] = 4 * (v - vmin - 0.25 * dv) / dv;
 
 3971          rgba[1] = 1 - rgba[0];
 
 3973       } 
else if (v < (vmin + 0.75 * dv)) {
 
 3974          rgba[1] = 4 * (v - vmin - 0.5 * dv) / dv;
 
 3975          rgba[0] = 1 - rgba[1];
 
 3979          rgba[2] = 4 * (v - vmin - 0.75 * dv) / dv;
 
 3980          rgba[1] = 1 - rgba[2];
 
 3984       if (v < (vmin + 0.5 * dv)) {
 
 3985          rgba[0] = 2 * (v - vmin) / dv;
 
 3989          rgba[0] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
 
 3995       if (v < (vmin + dv / 3)) {
 
 3996          rgba[2] = 3 * (v - vmin) / dv;
 
 3998          rgba[0] = 1 - rgba[2];
 
 3999       } 
else if (v < (vmin + 2 * dv / 3)) {
 
 4001          rgba[1] = 3 * (v - vmin - dv / 3) / dv;
 
 4004          rgba[0] = 3 * (v - vmin - 2 * dv / 3) / dv;
 
 4005          rgba[1] = 1 - rgba[0];
 
 4010       if (v < (vmin + 0.2 * dv)) {
 
 4012          rgba[1] = 5 * (v - vmin) / dv;
 
 4014       } 
else if (v < (vmin + 0.4 * dv)) {
 
 4017          rgba[2] = 1 + 5 * (vmin + 0.2 * dv - v) / dv;
 
 4018       } 
else if (v < (vmin + 0.6 * dv)) {
 
 4019          rgba[0] = 5 * (v - vmin - 0.4 * dv) / dv;
 
 4022       } 
else if (v < (vmin + 0.8 * dv)) {
 
 4024          rgba[1] = 1 - 5 * (v - vmin - 0.6 * dv) / dv;
 
 4028          rgba[1] = 5 * (v - vmin - 0.8 * dv) / dv;
 
 4029          rgba[2] = 5 * (v - vmin - 0.8 * dv) / dv;
 
 4033       c1[0] = 200 / 255.0; c1[1] =  60 / 255.0; c1[2] =   0 / 255.0;
 
 4034       c2[0] = 250 / 255.0; c2[1] = 160 / 255.0; c2[2] = 110 / 255.0;
 
 4035       rgba[0] = (c2[0] - c1[0]) * (v - vmin) / dv + c1[0];
 
 4036       rgba[1] = (c2[1] - c1[1]) * (v - vmin) / dv + c1[1];
 
 4037       rgba[2] = (c2[2] - c1[2]) * (v - vmin) / dv + c1[2];
 
 4040       c1[0] =  55 / 255.0; c1[1] =  55 / 255.0; c1[2] =  45 / 255.0;
 
 4041       c2[0] = 200 / 255.0; c2[1] =  60 / 255.0; c2[2] =   0 / 255.0;
 
 4042       c3[0] = 250 / 255.0; c3[1] = 160 / 255.0; c3[2] = 110 / 255.0;
 
 4044       vmid = vmin + ratio * dv;
 
 4046          rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
 
 4047          rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
 
 4048          rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
 
 4050          rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
 
 4051          rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
 
 4052          rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
 
 4056       c1[0] =   0 / 255.0; c1[1] = 255 / 255.0; c1[2] =   0 / 255.0;
 
 4057       c2[0] = 255 / 255.0; c2[1] = 150 / 255.0; c2[2] =   0 / 255.0;
 
 4058       c3[0] = 255 / 255.0; c3[1] = 250 / 255.0; c3[2] = 240 / 255.0;
 
 4060       vmid = vmin + ratio * dv;
 
 4062          rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
 
 4063          rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
 
 4064          rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
 
 4066          rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
 
 4067          rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
 
 4068          rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
 
 4073       rgba[1] = 1 - (v - vmin) / dv;
 
 4077       if (v < (vmin + 0.25 * dv)) {
 
 4079          rgba[1] = 4 * (v - vmin) / dv;
 
 4081       } 
else if (v < (vmin + 0.5 * dv)) {
 
 4084          rgba[2] = 1 - 4 * (v - vmin - 0.25 * dv) / dv;
 
 4085       } 
else if (v < (vmin + 0.75 * dv)) {
 
 4086          rgba[0] = 4 * (v - vmin - 0.5 * dv) / dv;
 
 4092          rgba[2] = 4 * (v - vmin - 0.75 * dv) / dv;
 
 4096       if (v < (vmin + 0.5 * dv)) {
 
 4098          rgba[1] = 2 * (v - vmin) / dv;
 
 4099          rgba[2] = 1 - 2 * (v - vmin) / dv;
 
 4101          rgba[0] = 2 * (v - vmin - 0.5 * dv) / dv;
 
 4102          rgba[1] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
 
 4107       if (v < (vmin + 0.5 * dv)) {
 
 4109          rgba[1] = 1 - 2 * (v - vmin) / dv;
 
 4110          rgba[2] = 2 * (v - vmin) / dv;
 
 4112          rgba[0] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
 
 4113          rgba[1] = 2 * (v - vmin - 0.5 * dv) / dv;
 
 4119       rgba[1] = (v - vmin) / (vmax - vmin);
 
 4123       rgba[0] = (v - vmin) / (vmax - vmin);
 
 4128       c1[0] =   0 / 255.0; c1[1] = 160 / 255.0; c1[2] =   0 / 255.0;
 
 4129       c2[0] = 180 / 255.0; c2[1] = 220 / 255.0; c2[2] =   0 / 255.0;
 
 4130       c3[0] = 250 / 255.0; c3[1] = 220 / 255.0; c3[2] = 170 / 255.0;
 
 4132       vmid = vmin + ratio * dv;
 
 4134          rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
 
 4135          rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
 
 4136          rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
 
 4138          rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
 
 4139          rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
 
 4140          rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
 
 4151 TGLLevelPalette::TGLLevelPalette()
 
 4162 Bool_t TGLLevelPalette::GeneratePalette(UInt_t paletteSize, 
const Rgl::Range_t &zRange, Bool_t check)
 
 4164    if (!fMaxPaletteSize && check)
 
 4165       glGetIntegerv(GL_MAX_TEXTURE_SIZE, &fMaxPaletteSize);
 
 4167    if (!(zRange.second - zRange.first))
 
 4171        Error(
"TGLLevelPaletter::GeneratePalette",
 
 4172              "Invalid palette size, must be a positive number");
 
 4176    if (check && paletteSize > UInt_t(fMaxPaletteSize)) {
 
 4177       Error(
"TGLLevelPalette::GeneratePalette",
 
 4178             "Number of contours %d is too big for GL 1D texture, try to reduce it to %d",
 
 4179             paletteSize, fMaxPaletteSize);
 
 4183    UInt_t nearestPow2 = 2;
 
 4184    while (nearestPow2 < paletteSize)
 
 4187    fTexels.resize(4 * nearestPow2);
 
 4188    fPaletteSize = paletteSize;
 
 4191    const Int_t nColors = gStyle->GetNumberOfColors();
 
 4195    for (UInt_t i = 0; i < paletteSize; ++i) {
 
 4196       Int_t paletteInd = Int_t(nColors / Double_t(paletteSize) * i);
 
 4197       if (paletteInd > nColors - 1)
 
 4198          paletteInd = nColors - 1;
 
 4199       Int_t colorInd = gStyle->GetColorPalette(paletteInd);
 
 4201       if (
const TColor *c = gROOT->GetColor(colorInd)) {
 
 4202          Float_t rgb[3] = {};
 
 4203          c->GetRGB(rgb[0], rgb[1], rgb[2]);
 
 4204          fTexels[i * 4]     = UChar_t(rgb[0] * 255);
 
 4205          fTexels[i * 4 + 1] = UChar_t(rgb[1] * 255);
 
 4206          fTexels[i * 4 + 2] = UChar_t(rgb[2] * 255);
 
 4207          fTexels[i * 4 + 3] = 200;
 
 4219 void TGLLevelPalette::SetContours(
const std::vector<Double_t> *cont)
 
 4227 void TGLLevelPalette::EnableTexture(Int_t mode)
const 
 4229    glEnable(GL_TEXTURE_1D);
 
 4231    glGenTextures(1, &fTexture);
 
 4233    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
 4234    glBindTexture(GL_TEXTURE_1D, fTexture);
 
 4235    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 
 4236    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
 4237    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
 4238    glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, fTexels.size() / 4, 0,
 
 4239                 GL_RGBA, GL_UNSIGNED_BYTE, &fTexels[0]);
 
 4240    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GLint(mode));
 
 4246 void TGLLevelPalette::DisableTexture()
const 
 4248    glDeleteTextures(1, &fTexture);
 
 4249    glDisable(GL_TEXTURE_1D);
 
 4255 Int_t TGLLevelPalette::GetPaletteSize()
const 
 4257    return Int_t(fPaletteSize);
 
 4263 Double_t TGLLevelPalette::GetTexCoord(Double_t z)
const 
 4266       if (z - fZRange.first < 0)
 
 4268       else if (fZRange.second < z)
 
 4271       return (z - fZRange.first) / (fZRange.second - fZRange.first) * fPaletteSize / (fTexels.size() / 4);
 
 4292 const UChar_t *TGLLevelPalette::GetColour(Double_t z)
const 
 4294    if (z - fZRange.first < 0)
 
 4296    else if (fZRange.second < z)
 
 4299    UInt_t ind = UInt_t((z - fZRange.first) / (fZRange.second - fZRange.first) * fPaletteSize);
 
 4300    if (ind >= fPaletteSize)
 
 4301       ind = fPaletteSize - 1;
 
 4303    return &fTexels[ind * 4];
 
 4309 const UChar_t *TGLLevelPalette::GetColour(Int_t ind)
const 
 4311    return &fTexels[ind * 4];