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];