Logo ROOT  
Reference Guide
TGLUtil.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Richard Maunder 25/05/2005
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <algorithm>
13#include <cassert>
14#include <string>
15#include <map>
16#include <iostream>
17
18#include "THLimitsFinder.h"
19#include "TVirtualPad.h"
20#include "TVirtualX.h"
21#include "TStyle.h"
22#include "TGaxis.h"
23#include "TColor.h"
24#include "TError.h"
25#include "TAxis.h"
26#include "TMath.h"
27#include "TROOT.h"
28#include "TEnv.h"
29
30#include "TGLBoundingBox.h"
31#include "TGLCamera.h"
32#include "TGLPlotPainter.h"
33#include "TGLIncludes.h"
34#include "TGLQuadric.h"
35#include "TGLUtil.h"
36
37/** \class TGLVertex3
38\ingroup opengl
393 component (x/y/z) vertex class.
40
41This is part of collection of simple utility classes for GL only in
42TGLUtil.h/cxx. These provide const and non-const accessors Arr() &
43CArr() to a GL compatible internal field - so can be used directly
44with OpenGL C API calls - which TVector3 etc cannot (easily).
45They are not intended to be fully featured just provide minimum required.
46*/
47
49
50////////////////////////////////////////////////////////////////////////////////
51/// Construct a default (0.0, 0.0, 0.0) vertex
52
54{
55 Fill(0.0);
56}
57
58////////////////////////////////////////////////////////////////////////////////
59/// Construct a vertex with components (x,y,z)
60
62{
63 Set(x,y,z);
64}
65
66////////////////////////////////////////////////////////////////////////////////
67/// Construct a vertex with components (v[0], v[1], v[2])
68
70{
71 Set(v[0], v[1], v[2]);
72}
73
74////////////////////////////////////////////////////////////////////////////////
75/// Construct a vertex from 'other'
76
78{
79 Set(other);
80}
81
82////////////////////////////////////////////////////////////////////////////////
83/// Destroy vertex object
84
86{
87}
88
89////////////////////////////////////////////////////////////////////////////////
90/// Offset a vertex by vector 'shift'
91
93{
94 fVals[0] += shift[0];
95 fVals[1] += shift[1];
96 fVals[2] += shift[2];
97}
98
99////////////////////////////////////////////////////////////////////////////////
100/// Offset a vertex by components (xDelta, yDelta, zDelta)
101
102void TGLVertex3::Shift(Double_t xDelta, Double_t yDelta, Double_t zDelta)
103{
104 fVals[0] += xDelta;
105 fVals[1] += yDelta;
106 fVals[2] += zDelta;
107}
108
109////////////////////////////////////////////////////////////////////////////////
110
112{
113 fVals[0] = TMath::Min(fVals[0], other.fVals[0]);
114 fVals[1] = TMath::Min(fVals[1], other.fVals[1]);
115 fVals[2] = TMath::Min(fVals[2], other.fVals[2]);
116}
117
118////////////////////////////////////////////////////////////////////////////////
119
121{
122 fVals[0] = TMath::Max(fVals[0], other.fVals[0]);
123 fVals[1] = TMath::Max(fVals[1], other.fVals[1]);
124 fVals[2] = TMath::Max(fVals[2], other.fVals[2]);
125}
126
127////////////////////////////////////////////////////////////////////////////////
128/// Output vertex component values to std::cout
129
131{
132 std::cout << "(" << fVals[0] << "," << fVals[1] << "," << fVals[2] << ")" << std::endl;
133}
134
135/** \class TGLVector3
136\ingroup opengl
1373 component (x/y/z) vector class.
138
139This is part of collection of utility classes for GL in TGLUtil.h/cxx
140These provide const and non-const accessors Arr() / CArr() to a GL
141compatible internal field - so can be used directly with OpenGL C API
142calls. They are not intended to be fully featured just provide
143minimum required.
144*/
145
147
148////////////////////////////////////////////////////////////////////////////////
149/// Construct a vector with components (x,y,z)
150
152 TGLVertex3(x, y, z)
153{
154}
155
156////////////////////////////////////////////////////////////////////////////////
157/// Construct a vector with components (src[0], src[1], src[2])
158
160 TGLVertex3(src[0], src[1], src[2])
161{
162}
163
164
165/** \class TGLLine3
166\ingroup opengl
1673D space, fixed length, line class, with direction / length 'vector',
168passing through point 'vertex'. Just wraps a TGLVector3 / TGLVertex3 pair.
169*/
170
172
173////////////////////////////////////////////////////////////////////////////////
174/// Construct 3D line running from 'start' to 'end'
175
176TGLLine3::TGLLine3(const TGLVertex3 & start, const TGLVertex3 & end) :
177 fVertex(start), fVector(end - start)
178{
179}
180
181////////////////////////////////////////////////////////////////////////////////
182/// Construct 3D line running from 'start', magnitude 'vect'
183
184TGLLine3::TGLLine3(const TGLVertex3 & start, const TGLVector3 & vect) :
185 fVertex(start), fVector(vect)
186{
187}
188
189////////////////////////////////////////////////////////////////////////////////
190/// Set 3D line running from 'start' to 'end'
191
192void TGLLine3::Set(const TGLVertex3 & start, const TGLVertex3 & end)
193{
194 fVertex = start;
195 fVector = end - start;
196}
197
198////////////////////////////////////////////////////////////////////////////////
199/// Set 3D line running from start, magnitude 'vect'
200
201void TGLLine3::Set(const TGLVertex3 & start, const TGLVector3 & vect)
202{
203 fVertex = start;
204 fVector = vect;
205}
206
207////////////////////////////////////////////////////////////////////////////////
208/// Draw line in current basic GL color. Assume we are in the correct reference
209/// frame
210
211void TGLLine3::Draw() const
212{
213 glBegin(GL_LINE_LOOP);
214 glVertex3dv(fVertex.CArr());
215 glVertex3dv(End().CArr());
216 glEnd();
217}
218
219/** \class TGLRect
220\ingroup opengl
221Viewport (pixel base) 2D rectangle class.
222*/
223
225
226////////////////////////////////////////////////////////////////////////////////
227/// Construct empty rect object, corner (0,0), width/height 0
228
230 fX(0), fY(0), fWidth(0), fHeight(0)
231{
232}
233
234////////////////////////////////////////////////////////////////////////////////
235/// Construct rect object, corner (x,y), dimensions 'width', 'height'
236
238 fX(x), fY(y), fWidth(width), fHeight(height)
239{
240}
241
242////////////////////////////////////////////////////////////////////////////////
243/// Construct rect object, corner (x,y), dimensions 'width', 'height'
244
246 fX(x), fY(y), fWidth(width), fHeight(height)
247{
248}
249
250
251////////////////////////////////////////////////////////////////////////////////
252/// Destroy rect object
253
255{
256}
257
258////////////////////////////////////////////////////////////////////////////////
259/// Expand the rect to encompass point (x,y)
260
262{
263 Int_t delX = x - fX;
264 Int_t delY = y - fY;
265
266 if (delX > fWidth) {
267 fWidth = delX;
268 }
269 if (delY > fHeight) {
270 fHeight = delY;
271 }
272
273 if (delX < 0) {
274 fX = x;
275 fWidth += -delX;
276 }
277 if (delY < 0) {
278 fY = y;
279 fHeight += -delY;
280 }
281}
282
283////////////////////////////////////////////////////////////////////////////////
284/// Return the diagonal of the rectangle.
285
287{
288 const Double_t w = static_cast<Double_t>(fWidth);
289 const Double_t h = static_cast<Double_t>(fHeight);
290 return TMath::Nint(TMath::Sqrt(w*w + h*h));
291}
292
293////////////////////////////////////////////////////////////////////////////////
294/// Return overlap result (kInside, kOutside, kPartial) of this
295/// rect with 'other'
296
298{
299 using namespace Rgl;
300
301 if ((fX <= other.fX) && (fX + fWidth >= other.fX + other.fWidth) &&
302 (fY <= other.fY) && (fY + fHeight >= other.fY + other.fHeight))
303 {
304 return kInside;
305 }
306 else if ((fX >= other.fX + static_cast<Int_t>(other.fWidth)) ||
307 (fX + static_cast<Int_t>(fWidth) <= other.fX) ||
308 (fY >= other.fY + static_cast<Int_t>(other.fHeight)) ||
309 (fY + static_cast<Int_t>(fHeight) <= other.fY))
310 {
311 return kOutside;
312 }
313 else
314 {
315 return kPartial;
316 }
317}
318
319/** \class TGLPlane
320\ingroup opengl
3213D plane class - of format Ax + By + Cz + D = 0
322
323This is part of collection of simple utility classes for GL only in
324TGLUtil.h/cxx. These provide const and non-const accessors Arr() &
325CArr() to a GL compatible internal field - so can be used directly
326with OpenGL C API calls - which TVector3 etc cannot (easily).
327They are not intended to be fully featured just provide minimum
328required.
329*/
330
332
333////////////////////////////////////////////////////////////////////////////////
334/// Construct a default plane of x + y + z = 0
335
337{
338 Set(1.0, 1.0, 1.0, 0.0);
339}
340
341////////////////////////////////////////////////////////////////////////////////
342/// Construct plane from 'other'
343
345{
346 Set(other);
347}
348
349////////////////////////////////////////////////////////////////////////////////
350/// Construct plane with equation a.x + b.y + c.z + d = 0
351/// with optional normalisation
352
354{
355 Set(a, b, c, d);
356}
357
358////////////////////////////////////////////////////////////////////////////////
359/// Construct plane with equation eq[0].x + eq[1].y + eq[2].z + eq[3] = 0
360/// with optional normalisation
361
363{
364 Set(eq);
365}
366
367////////////////////////////////////////////////////////////////////////////////
368/// Construct plane passing through 3 supplied points
369/// with optional normalisation
370
372 const TGLVertex3 & p3)
373{
374 Set(p1, p2, p3);
375}
376
377////////////////////////////////////////////////////////////////////////////////
378/// Construct plane with supplied normal vector, passing through point
379/// with optional normalisation
380
382{
383 Set(v, p);
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// Assignment operator
388
390{
391 Set(src);
392 return *this;
393}
394
395////////////////////////////////////////////////////////////////////////////////
396/// Normalise the plane.
397
399{
400 Double_t mag = sqrt(fVals[0]*fVals[0] + fVals[1]*fVals[1] + fVals[2]*fVals[2]);
401
402 if (mag == 0.0 ) {
403 Error("TGLPlane::Normalise", "trying to normalise plane with zero magnitude normal");
404 return;
405 }
406 mag = 1.0 / mag;
407 fVals[0] *= mag;
408 fVals[1] *= mag;
409 fVals[2] *= mag;
410 fVals[3] *= mag;
411}
412
413////////////////////////////////////////////////////////////////////////////////
414/// Output plane equation to std::out
415
416void TGLPlane::Dump() const
417{
418 std::cout.precision(6);
419 std::cout << "Plane : " << fVals[0] << "x + " << fVals[1] << "y + " << fVals[2] << "z + " << fVals[3] << std::endl;
420}
421
422////////////////////////////////////////////////////////////////////////////////
423/// Assign from other.
424
425void TGLPlane::Set(const TGLPlane & other)
426{
427 fVals[0] = other.fVals[0];
428 fVals[1] = other.fVals[1];
429 fVals[2] = other.fVals[2];
430 fVals[3] = other.fVals[3];
431}
432
433////////////////////////////////////////////////////////////////////////////////
434/// Set by values.
435
437{
438 fVals[0] = a;
439 fVals[1] = b;
440 fVals[2] = c;
441 fVals[3] = d;
442 Normalise();
443}
444
445////////////////////////////////////////////////////////////////////////////////
446/// Set by array values.
447
449{
450 fVals[0] = eq[0];
451 fVals[1] = eq[1];
452 fVals[2] = eq[2];
453 fVals[3] = eq[3];
454 Normalise();
455}
456
457////////////////////////////////////////////////////////////////////////////////
458/// Set plane from a normal vector and in-plane point pair
459
460void TGLPlane::Set(const TGLVector3 & norm, const TGLVertex3 & point)
461{
462 fVals[0] = norm[0];
463 fVals[1] = norm[1];
464 fVals[2] = norm[2];
465 fVals[3] = -(fVals[0]*point[0] + fVals[1]*point[1] + fVals[2]*point[2]);
466 Normalise();
467}
468
469////////////////////////////////////////////////////////////////////////////////
470/// Set plane by three points.
471
472void TGLPlane::Set(const TGLVertex3 & p1, const TGLVertex3 & p2, const TGLVertex3 & p3)
473{
474 TGLVector3 norm = Cross(p2 - p1, p3 - p1);
475 Set(norm, p2);
476}
477
478////////////////////////////////////////////////////////////////////////////////
479/// Negate the plane.
480
482{
483 fVals[0] = -fVals[0];
484 fVals[1] = -fVals[1];
485 fVals[2] = -fVals[2];
486 fVals[3] = -fVals[3];
487}
488
489////////////////////////////////////////////////////////////////////////////////
490/// Distance from plane to vertex.
491
493{
494 return (fVals[0]*vertex[0] + fVals[1]*vertex[1] + fVals[2]*vertex[2] + fVals[3]);
495}
496
497////////////////////////////////////////////////////////////////////////////////
498/// Return nearest point on plane.
499
501{
502 TGLVector3 o = Norm() * (Dot(Norm(), TGLVector3(point[0], point[1], point[2])) + D() / Dot(Norm(), Norm()));
503 TGLVertex3 v = point - o;
504 return v;
505}
506
507// Some free functions for plane intersections
508
509////////////////////////////////////////////////////////////////////////////////
510/// Find 3D line interestion of this plane with 'other'. Returns a std::pair
511///
512/// first (Bool_t) second (TGLLine3)
513/// kTRUE - planes intersect intersection line between planes
514/// kFALSE - no intersect (parallel) undefined
515
516std::pair<Bool_t, TGLLine3> Intersection(const TGLPlane & p1, const TGLPlane & p2)
517{
518 TGLVector3 lineDir = Cross(p1.Norm(), p2.Norm());
519
520 if (lineDir.Mag() == 0.0) {
521 return std::make_pair(kFALSE, TGLLine3(TGLVertex3(0.0, 0.0, 0.0),
522 TGLVector3(0.0, 0.0, 0.0)));
523 }
524 TGLVertex3 linePoint = Cross((p1.Norm()*p2.D() - p2.Norm()*p1.D()), lineDir) /
525 Dot(lineDir, lineDir);
526 return std::make_pair(kTRUE, TGLLine3(linePoint, lineDir));
527}
528
529////////////////////////////////////////////////////////////////////////////////
530
531std::pair<Bool_t, TGLVertex3> Intersection(const TGLPlane & p1, const TGLPlane & p2, const TGLPlane & p3)
532{
533 Double_t denom = Dot(p1.Norm(), Cross(p2.Norm(), p3.Norm()));
534 if (denom == 0.0) {
535 return std::make_pair(kFALSE, TGLVertex3(0.0, 0.0, 0.0));
536 }
537 TGLVector3 vect = ((Cross(p2.Norm(),p3.Norm())* -p1.D()) -
538 (Cross(p3.Norm(),p1.Norm())*p2.D()) -
539 (Cross(p1.Norm(),p2.Norm())*p3.D())) / denom;
540 TGLVertex3 interVert(vect.X(), vect.Y(), vect.Z());
541 return std::make_pair(kTRUE, interVert);
542}
543
544////////////////////////////////////////////////////////////////////////////////
545/// Find intersection of 3D space 'line' with this plane. If 'extend' is kTRUE
546/// then line extents can be extended (infinite length) to find intersection.
547/// If 'extend' is kFALSE the fixed extents of line is respected.
548///
549/// The return a std::pair
550///
551/// - first (Bool_t) second (TGLVertex3)
552/// - kTRUE - line/plane intersect intersection vertex on plane
553/// - kFALSE - no line/plane intersect undefined
554///
555/// If intersection is not found (first == kFALSE) & 'extend' was kTRUE (infinite line)
556/// this implies line and plane are parallel. If 'extend' was kFALSE, then
557/// either line parallel or insufficient length.
558
559std::pair<Bool_t, TGLVertex3> Intersection(const TGLPlane & plane, const TGLLine3 & line, Bool_t extend)
560{
561 Double_t denom = -(plane.A()*line.Vector().X() +
562 plane.B()*line.Vector().Y() +
563 plane.C()*line.Vector().Z());
564
565 if (denom == 0.0) {
566 return std::make_pair(kFALSE, TGLVertex3(0.0, 0.0, 0.0));
567 }
568
569 Double_t num = plane.A()*line.Start().X() + plane.B()*line.Start().Y() +
570 plane.C()*line.Start().Z() + plane.D();
571 Double_t factor = num/denom;
572
573 // If not extending (projecting) line is length from start enough to reach plane?
574 if (!extend && (factor < 0.0 || factor > 1.0)) {
575 return std::make_pair(kFALSE, TGLVertex3(0.0, 0.0, 0.0));
576 }
577
578 TGLVector3 toPlane = line.Vector() * factor;
579 return std::make_pair(kTRUE, line.Start() + toPlane);
580}
581
582/** \class TGLMatrix
583\ingroup opengl
58416 component (4x4) transform matrix - column MAJOR as per GL.
585Provides limited support for adjusting the translation, scale and
586rotation components.
587
588This is part of collection of simple utility classes for GL only in
589TGLUtil.h/cxx. These provide const and non-const accessors Arr() &
590CArr() to a GL compatible internal field - so can be used directly
591with OpenGL C API calls - which TVector3 etc cannot (easily).
592They are not intended to be fully featured just provide minimum
593required.
594*/
595
597
598////////////////////////////////////////////////////////////////////////////////
599/// Construct default identity matrix:
600///
601/// 1 0 0 0
602/// 0 1 0 0
603/// 0 0 1 0
604/// 0 0 0 1
605
607{
608 SetIdentity();
609}
610
611////////////////////////////////////////////////////////////////////////////////
612/// Construct matrix with translation components x,y,z:
613///
614/// 1 0 0 x
615/// 0 1 0 y
616/// 0 0 1 z
617/// 0 0 0 1
618
620{
621 SetIdentity();
622 SetTranslation(x, y, z);
623}
624
625////////////////////////////////////////////////////////////////////////////////
626/// Construct matrix with translation components x,y,z:
627///
628/// 1 0 0 translation.X()
629/// 0 1 0 translation.Y()
630/// 0 0 1 translation.Z()
631/// 0 0 0 1
632
634{
635 SetIdentity();
636 SetTranslation(translation);
637}
638
639////////////////////////////////////////////////////////////////////////////////
640/// Construct matrix which when applied puts local origin at
641/// 'origin' and the local Z axis in direction 'z'. Both
642/// 'origin' and 'zAxisVec' are expressed in the parent frame
643
644TGLMatrix::TGLMatrix(const TGLVertex3 & origin, const TGLVector3 & zAxis)
645{
646 SetIdentity();
647
648 TGLVector3 zAxisInt(zAxis);
649 zAxisInt.Normalise();
650 TGLVector3 arbAxis;
651
652 if (TMath::Abs(zAxisInt.X()) <= TMath::Abs(zAxisInt.Y()) && TMath::Abs(zAxisInt.X()) <= TMath::Abs(zAxisInt.Z())) {
653 arbAxis.Set(1.0, 0.0, 0.0);
654 } else if (TMath::Abs(zAxisInt.Y()) <= TMath::Abs(zAxisInt.X()) && TMath::Abs(zAxisInt.Y()) <= TMath::Abs(zAxisInt.Z())) {
655 arbAxis.Set(0.0, 1.0, 0.0);
656 } else {
657 arbAxis.Set(0.0, 0.0, 1.0);
658 }
659
660 Set(origin, zAxis, Cross(zAxisInt, arbAxis));
661}
662
663////////////////////////////////////////////////////////////////////////////////
664/// Construct matrix which when applied puts local origin at
665/// 'origin' and the local Z axis in direction 'z'. Both
666/// 'origin' and 'zAxisVec' are expressed in the parent frame
667
668TGLMatrix::TGLMatrix(const TGLVertex3 & origin, const TGLVector3 & zAxis, const TGLVector3 & xAxis)
669{
670 SetIdentity();
671 Set(origin, zAxis, xAxis);
672}
673
674////////////////////////////////////////////////////////////////////////////////
675/// Construct matrix using the 16 Double_t 'vals' passed,
676/// ordering is maintained - i.e. should be column major
677/// as we are
678
680{
681 Set(vals);
682}
683
684////////////////////////////////////////////////////////////////////////////////
685/// Construct matrix from 'other'
686
688{
689 *this = other;
690}
691
692////////////////////////////////////////////////////////////////////////////////
693/// Destroy matrix object
694
696{
697}
698
699////////////////////////////////////////////////////////////////////////////////
700/// Multiply with matrix rhs on right.
701
703{
704 Double_t B[4];
705 Double_t* C = fVals;
706 for(int r=0; r<4; ++r, ++C)
707 {
708 const Double_t* T = rhs.fVals;
709 for(int c=0; c<4; ++c, T+=4)
710 B[c] = C[0]*T[0] + C[4]*T[1] + C[8]*T[2] + C[12]*T[3];
711 C[0] = B[0]; C[4] = B[1]; C[8] = B[2]; C[12] = B[3];
712 }
713}
714
715////////////////////////////////////////////////////////////////////////////////
716/// Multiply with matrix lhs on left.
717
719{
720 Double_t B[4];
721 Double_t* C = fVals;
722 for (int c=0; c<4; ++c, C+=4)
723 {
724 const Double_t* T = lhs.fVals;
725 for(int r=0; r<4; ++r, ++T)
726 B[r] = T[0]*C[0] + T[4]*C[1] + T[8]*C[2] + T[12]*C[3];
727 C[0] = B[0]; C[1] = B[1]; C[2] = B[2]; C[3] = B[3];
728 }
729}
730
731////////////////////////////////////////////////////////////////////////////////
732/// Set matrix which when applied puts local origin at
733/// 'origin' and the local Z axis in direction 'z'. Both
734/// 'origin' and 'z' are expressed in the parent frame
735
736void TGLMatrix::Set(const TGLVertex3 & origin, const TGLVector3 & zAxis, const TGLVector3 & xAxis)
737{
738 TGLVector3 zAxisInt(zAxis);
739 zAxisInt.Normalise();
740
741 TGLVector3 xAxisInt(xAxis);
742 xAxisInt.Normalise();
743 TGLVector3 yAxisInt = Cross(zAxisInt, xAxisInt);
744
745 fVals[0] = xAxisInt.X(); fVals[4] = yAxisInt.X(); fVals[8 ] = zAxisInt.X(); fVals[12] = origin.X();
746 fVals[1] = xAxisInt.Y(); fVals[5] = yAxisInt.Y(); fVals[9 ] = zAxisInt.Y(); fVals[13] = origin.Y();
747 fVals[2] = xAxisInt.Z(); fVals[6] = yAxisInt.Z(); fVals[10] = zAxisInt.Z(); fVals[14] = origin.Z();
748 fVals[3] = 0.0; fVals[7] = 0.0; fVals[11] = 0.0; fVals[15] = 1.0;
749}
750
751////////////////////////////////////////////////////////////////////////////////
752/// Set matrix using the 16 Double_t 'vals' passed,
753/// ordering is maintained - i.e. should be column major.
754
755void TGLMatrix::Set(const Double_t vals[16])
756{
757 for (UInt_t i=0; i < 16; i++) {
758 fVals[i] = vals[i];
759 }
760}
761
762////////////////////////////////////////////////////////////////////////////////
763/// Set matrix to identity.
764
766{
767 fVals[0] = 1.0; fVals[4] = 0.0; fVals[8 ] = 0.0; fVals[12] = 0.0;
768 fVals[1] = 0.0; fVals[5] = 1.0; fVals[9 ] = 0.0; fVals[13] = 0.0;
769 fVals[2] = 0.0; fVals[6] = 0.0; fVals[10] = 1.0; fVals[14] = 0.0;
770 fVals[3] = 0.0; fVals[7] = 0.0; fVals[11] = 0.0; fVals[15] = 1.0;
771}
772
773////////////////////////////////////////////////////////////////////////////////
774/// Set matrix translation components x,y,z.
775
777{
779}
780
781////////////////////////////////////////////////////////////////////////////////
782/// Set matrix translation components x,y,z.
783
784void TGLMatrix::SetTranslation(const TGLVertex3 & translation)
785{
786 fVals[12] = translation[0];
787 fVals[13] = translation[1];
788 fVals[14] = translation[2];
789}
790
791////////////////////////////////////////////////////////////////////////////////
792/// Return the translation component of matrix.
793
795{
796 return TGLVector3(fVals[12], fVals[13], fVals[14]);
797}
798
799////////////////////////////////////////////////////////////////////////////////
800/// Shift matrix translation components by 'vect' in parent frame.
801
803{
804 fVals[12] += vect[0];
805 fVals[13] += vect[1];
806 fVals[14] += vect[2];
807}
808
809////////////////////////////////////////////////////////////////////////////////
810/// Translate in local frame.
811/// i1, i2 are axes indices: 1 ~ x, 2 ~ y, 3 ~ z.
812
814{
815 const Double_t *C = fVals + 4*--ai;
816 fVals[12] += amount*C[0]; fVals[13] += amount*C[1]; fVals[14] += amount*C[2];
817}
818
819////////////////////////////////////////////////////////////////////////////////
820/// Translate in local frame along all base vectors simultaneously.
821
823{
824 fVals[12] += x*fVals[0] + y*fVals[4] + z*fVals[8];
825 fVals[13] += x*fVals[1] + y*fVals[5] + z*fVals[9];
826 fVals[14] += x*fVals[2] + y*fVals[6] + z*fVals[10];
827}
828
829////////////////////////////////////////////////////////////////////////////////
830/// Set matrix axis scales to 'scale'. Note - this really sets
831/// the overall (total) scaling for each axis - it does NOT
832/// apply compounded scale on top of existing one
833
834void TGLMatrix::Scale(const TGLVector3 & scale)
835{
836 TGLVector3 currentScale = GetScale();
837
838 // x
839 if (currentScale[0] != 0.0) {
840 fVals[0] *= scale[0]/currentScale[0];
841 fVals[1] *= scale[0]/currentScale[0];
842 fVals[2] *= scale[0]/currentScale[0];
843 } else {
844 Error("TGLMatrix::Scale()", "zero scale div by zero");
845 }
846 // y
847 if (currentScale[1] != 0.0) {
848 fVals[4] *= scale[1]/currentScale[1];
849 fVals[5] *= scale[1]/currentScale[1];
850 fVals[6] *= scale[1]/currentScale[1];
851 } else {
852 Error("TGLMatrix::Scale()", "zero scale div by zero");
853 }
854 // z
855 if (currentScale[2] != 0.0) {
856 fVals[8] *= scale[2]/currentScale[2];
857 fVals[9] *= scale[2]/currentScale[2];
858 fVals[10] *= scale[2]/currentScale[2];
859 } else {
860 Error("TGLMatrix::Scale()", "zero scale div by zero");
861 }
862}
863
864////////////////////////////////////////////////////////////////////////////////
865/// Update matrix so resulting transform has been rotated about 'pivot'
866/// (in parent frame), round vector 'axis', through 'angle' (radians)
867/// Equivalent to glRotate function, but with addition of translation
868/// and compounded on top of existing.
869
870void TGLMatrix::Rotate(const TGLVertex3 & pivot, const TGLVector3 & axis, Double_t angle)
871{
872 TGLVector3 nAxis = axis;
873 nAxis.Normalise();
874 Double_t x = nAxis.X();
875 Double_t y = nAxis.Y();
876 Double_t z = nAxis.Z();
877 Double_t c = TMath::Cos(angle);
878 Double_t s = TMath::Sin(angle);
879
880 // Calculate local rotation, with pre-translation to local pivot origin
881 TGLMatrix rotMat;
882 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];
883 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];
884 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];
885 rotMat[ 3] = 0.0; rotMat[ 7] = 0.0; rotMat[11] = 0.0; rotMat[15] = 1.0;
886 TGLMatrix localToWorld(-pivot);
887
888 // TODO: Ugly - should use quaternions to avoid compound rounding errors and
889 // triple multiplication
890 *this = rotMat * localToWorld * (*this);
891}
892
893////////////////////////////////////////////////////////////////////////////////
894/// Rotate in local frame. Does optimised version of MultRight.
895/// i1, i2 are axes indices: 1 ~ x, 2 ~ y, 3 ~ z.
896
898{
899 if(i1 == i2) return;
900 const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount);
901 Double_t b1, b2;
902 Double_t* c = fVals;
903 --i1 <<= 2; --i2 <<= 2; // column major
904 for(int r=0; r<4; ++r, ++c) {
905 b1 = cos*c[i1] + sin*c[i2];
906 b2 = cos*c[i2] - sin*c[i1];
907 c[i1] = b1; c[i2] = b2;
908 }
909}
910
911////////////////////////////////////////////////////////////////////////////////
912/// Rotate in parent frame. Does optimised version of MultLeft.
913
915{
916 if(i1 == i2) return;
917
918 // Optimized version:
919 const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount);
920 Double_t b1, b2;
921 Double_t* C = fVals;
922 --i1; --i2;
923 for(int c=0; c<4; ++c, C+=4) {
924 b1 = cos*C[i1] - sin*C[i2];
925 b2 = cos*C[i2] + sin*C[i1];
926 C[i1] = b1; C[i2] = b2;
927 }
928}
929
930////////////////////////////////////////////////////////////////////////////////
931/// Transform passed 'vertex' by this matrix - converts local frame to parent
932
934{
935 TGLVertex3 orig = vertex;
936 for (UInt_t i = 0; i < 3; i++) {
937 vertex[i] = orig[0] * fVals[0+i] + orig[1] * fVals[4+i] +
938 orig[2] * fVals[8+i] + fVals[12+i];
939 }
940}
941
942////////////////////////////////////////////////////////////////////////////////
943/// Transpose the top left 3x3 matrix component along major diagonal
944/// Supported as currently incompatibility between TGeo and GL matrix
945/// layouts for this 3x3 only. To be resolved.
946
948{
949 // TODO: Move this fix to the TBuffer3D filling side and remove
950 //
951 // 0 4 8 12
952 // 1 5 9 13
953 // 2 6 10 14
954 // 3 7 11 15
955
956 Double_t temp = fVals[4];
957 fVals[4] = fVals[1];
958 fVals[1] = temp;
959 temp = fVals[8];
960 fVals[8] = fVals[2];
961 fVals[2] = temp;
962 temp = fVals[9];
963 fVals[9] = fVals[6];
964 fVals[6] = temp;
965}
966
967////////////////////////////////////////////////////////////////////////////////
968/// Invert the matrix, returns determinant.
969/// Copied from TMatrixFCramerInv.
970
972{
973 Double_t* M = fVals;
974
975 const Double_t det2_12_01 = M[1]*M[6] - M[5]*M[2];
976 const Double_t det2_12_02 = M[1]*M[10] - M[9]*M[2];
977 const Double_t det2_12_03 = M[1]*M[14] - M[13]*M[2];
978 const Double_t det2_12_13 = M[5]*M[14] - M[13]*M[6];
979 const Double_t det2_12_23 = M[9]*M[14] - M[13]*M[10];
980 const Double_t det2_12_12 = M[5]*M[10] - M[9]*M[6];
981 const Double_t det2_13_01 = M[1]*M[7] - M[5]*M[3];
982 const Double_t det2_13_02 = M[1]*M[11] - M[9]*M[3];
983 const Double_t det2_13_03 = M[1]*M[15] - M[13]*M[3];
984 const Double_t det2_13_12 = M[5]*M[11] - M[9]*M[7];
985 const Double_t det2_13_13 = M[5]*M[15] - M[13]*M[7];
986 const Double_t det2_13_23 = M[9]*M[15] - M[13]*M[11];
987 const Double_t det2_23_01 = M[2]*M[7] - M[6]*M[3];
988 const Double_t det2_23_02 = M[2]*M[11] - M[10]*M[3];
989 const Double_t det2_23_03 = M[2]*M[15] - M[14]*M[3];
990 const Double_t det2_23_12 = M[6]*M[11] - M[10]*M[7];
991 const Double_t det2_23_13 = M[6]*M[15] - M[14]*M[7];
992 const Double_t det2_23_23 = M[10]*M[15] - M[14]*M[11];
993
994
995 const Double_t det3_012_012 = M[0]*det2_12_12 - M[4]*det2_12_02 + M[8]*det2_12_01;
996 const Double_t det3_012_013 = M[0]*det2_12_13 - M[4]*det2_12_03 + M[12]*det2_12_01;
997 const Double_t det3_012_023 = M[0]*det2_12_23 - M[8]*det2_12_03 + M[12]*det2_12_02;
998 const Double_t det3_012_123 = M[4]*det2_12_23 - M[8]*det2_12_13 + M[12]*det2_12_12;
999 const Double_t det3_013_012 = M[0]*det2_13_12 - M[4]*det2_13_02 + M[8]*det2_13_01;
1000 const Double_t det3_013_013 = M[0]*det2_13_13 - M[4]*det2_13_03 + M[12]*det2_13_01;
1001 const Double_t det3_013_023 = M[0]*det2_13_23 - M[8]*det2_13_03 + M[12]*det2_13_02;
1002 const Double_t det3_013_123 = M[4]*det2_13_23 - M[8]*det2_13_13 + M[12]*det2_13_12;
1003 const Double_t det3_023_012 = M[0]*det2_23_12 - M[4]*det2_23_02 + M[8]*det2_23_01;
1004 const Double_t det3_023_013 = M[0]*det2_23_13 - M[4]*det2_23_03 + M[12]*det2_23_01;
1005 const Double_t det3_023_023 = M[0]*det2_23_23 - M[8]*det2_23_03 + M[12]*det2_23_02;
1006 const Double_t det3_023_123 = M[4]*det2_23_23 - M[8]*det2_23_13 + M[12]*det2_23_12;
1007 const Double_t det3_123_012 = M[1]*det2_23_12 - M[5]*det2_23_02 + M[9]*det2_23_01;
1008 const Double_t det3_123_013 = M[1]*det2_23_13 - M[5]*det2_23_03 + M[13]*det2_23_01;
1009 const Double_t det3_123_023 = M[1]*det2_23_23 - M[9]*det2_23_03 + M[13]*det2_23_02;
1010 const Double_t det3_123_123 = M[5]*det2_23_23 - M[9]*det2_23_13 + M[13]*det2_23_12;
1011
1012 const Double_t det = M[0]*det3_123_123 - M[4]*det3_123_023 +
1013 M[8]*det3_123_013 - M[12]*det3_123_012;
1014
1015 if(det == 0) {
1016 Warning("TGLMatrix::Invert", "matrix is singular.");
1017 return 0;
1018 }
1019
1020 const Double_t oneOverDet = 1.0/det;
1021 const Double_t mn1OverDet = - oneOverDet;
1022
1023 M[0] = det3_123_123 * oneOverDet;
1024 M[4] = det3_023_123 * mn1OverDet;
1025 M[8] = det3_013_123 * oneOverDet;
1026 M[12] = det3_012_123 * mn1OverDet;
1027
1028 M[1] = det3_123_023 * mn1OverDet;
1029 M[5] = det3_023_023 * oneOverDet;
1030 M[9] = det3_013_023 * mn1OverDet;
1031 M[13] = det3_012_023 * oneOverDet;
1032
1033 M[2] = det3_123_013 * oneOverDet;
1034 M[6] = det3_023_013 * mn1OverDet;
1035 M[10] = det3_013_013 * oneOverDet;
1036 M[14] = det3_012_013 * mn1OverDet;
1037
1038 M[3] = det3_123_012 * mn1OverDet;
1039 M[7] = det3_023_012 * oneOverDet;
1040 M[11] = det3_013_012 * mn1OverDet;
1041 M[15] = det3_012_012 * oneOverDet;
1042
1043 return det;
1044}
1045
1046////////////////////////////////////////////////////////////////////////////////
1047/// Multiply vector.
1048
1050{
1051 const Double_t* M = fVals;
1052 TGLVector3 r;
1053 r.X() = M[0]*v[0] + M[4]*v[1] + M[8]*v[2] + M[12]*w;
1054 r.Y() = M[1]*v[0] + M[5]*v[1] + M[9]*v[2] + M[13]*w;
1055 r.Z() = M[2]*v[0] + M[6]*v[1] + M[10]*v[2] + M[14]*w;
1056 return r;
1057}
1058
1059////////////////////////////////////////////////////////////////////////////////
1060/// Rotate vector. Translation is not applied.
1061
1063{
1064 const Double_t* M = fVals;
1065 TGLVector3 r;
1066 r.X() = M[0]*v[0] + M[4]*v[1] + M[8]*v[2];
1067 r.Y() = M[1]*v[0] + M[5]*v[1] + M[9]*v[2];
1068 r.Z() = M[2]*v[0] + M[6]*v[1] + M[10]*v[2];
1069 return r;
1070}
1071
1072////////////////////////////////////////////////////////////////////////////////
1073/// Multiply vector in-place.
1074
1076{
1077 const Double_t* M = fVals;
1078 Double_t r[3] = { v[0], v[1], v[2] };
1079 v.X() = M[0]*r[0] + M[4]*r[1] + M[8]*r[2] + M[12]*w;
1080 v.Y() = M[1]*r[0] + M[5]*r[1] + M[9]*r[2] + M[13]*w;
1081 v.Z() = M[2]*r[0] + M[6]*r[1] + M[10]*r[2] + M[14]*w;
1082}
1083
1084////////////////////////////////////////////////////////////////////////////////
1085/// Rotate vector in-place. Translation is not applied.
1086
1088{
1089 const Double_t* M = fVals;
1090 Double_t r[3] = { v[0], v[1], v[2] };
1091 v.X() = M[0]*r[0] + M[4]*r[1] + M[8]*r[2];
1092 v.Y() = M[1]*r[0] + M[5]*r[1] + M[9]*r[2];
1093 v.Z() = M[2]*r[0] + M[6]*r[1] + M[10]*r[2];
1094}
1095
1096////////////////////////////////////////////////////////////////////////////////
1097/// Get local axis scaling factors
1098
1100{
1101 TGLVector3 x(fVals[0], fVals[1], fVals[2]);
1102 TGLVector3 y(fVals[4], fVals[5], fVals[6]);
1103 TGLVector3 z(fVals[8], fVals[9], fVals[10]);
1104 return TGLVector3(x.Mag(), y.Mag(), z.Mag());
1105}
1106
1107////////////////////////////////////////////////////////////////////////////////
1108/// Return true if matrix is to be considered a scaling matrix
1109/// for rendering.
1110
1112{
1113 Double_t ss;
1114 ss = fVals[0]*fVals[0] + fVals[1]*fVals[1] + fVals[2]*fVals[2];
1115 if (ss < 0.8 || ss > 1.2) return kTRUE;
1116 ss = fVals[4]*fVals[4] + fVals[5]*fVals[5] + fVals[6]*fVals[6];
1117 if (ss < 0.8 || ss > 1.2) return kTRUE;
1118 ss = fVals[8]*fVals[8] + fVals[9]*fVals[9] + fVals[10]*fVals[10];
1119 if (ss < 0.8 || ss > 1.2) return kTRUE;
1120 return kFALSE;
1121}
1122
1123////////////////////////////////////////////////////////////////////////////////
1124/// Output 16 matrix components to std::cout
1125///
1126/// 0 4 8 12
1127/// 1 5 9 13
1128/// 2 6 10 14
1129/// 3 7 11 15
1130///
1131
1133{
1134 std::cout.precision(6);
1135 for (Int_t x = 0; x < 4; x++) {
1136 std::cout << "[ ";
1137 for (Int_t y = 0; y < 4; y++) {
1138 std::cout << fVals[y*4 + x] << " ";
1139 }
1140 std::cout << "]" << std::endl;
1141 }
1142}
1143
1144
1145/** \class TGLColor
1146\ingroup opengl
1147Class encapsulating color information in preferred GL format - an
1148array of four unsigned bytes.
1149Color index is also cached for easier interfacing with the
1150traditional ROOT graphics.
1151*/
1152
1154
1155////////////////////////////////////////////////////////////////////////////////
1156/// Default constructor. Color is initialized to black.
1157
1159{
1160 fRGBA[0] = fRGBA[1] = fRGBA[2] = 0;
1161 fRGBA[3] = 255;
1162 fIndex = -1;
1163}
1164
1165////////////////////////////////////////////////////////////////////////////////
1166/// Constructor from Int_t values.
1167
1169{
1170 SetColor(r, g, b, a);
1171}
1172
1173////////////////////////////////////////////////////////////////////////////////
1174/// Constructor from Float_t values.
1175
1177{
1178 SetColor(r, g, b, a);
1179}
1180
1181////////////////////////////////////////////////////////////////////////////////
1182/// Constructor from color-index and transparency.
1183
1184TGLColor::TGLColor(Color_t color_index, Char_t transparency)
1185{
1186 SetColor(color_index, transparency);
1187}
1188
1189////////////////////////////////////////////////////////////////////////////////
1190/// copy constructor
1191
1193{
1194 fRGBA[0] = c.fRGBA[0];
1195 fRGBA[1] = c.fRGBA[1];
1196 fRGBA[2] = c.fRGBA[2];
1197 fRGBA[3] = c.fRGBA[3];
1198 fIndex = c.fIndex;
1199}
1200
1201////////////////////////////////////////////////////////////////////////////////
1202/// Assignment operator.
1203
1205{
1206 fRGBA[0] = c.fRGBA[0];
1207 fRGBA[1] = c.fRGBA[1];
1208 fRGBA[2] = c.fRGBA[2];
1209 fRGBA[3] = c.fRGBA[3];
1210 fIndex = c.fIndex;
1211 return *this;
1212}
1213
1214////////////////////////////////////////////////////////////////////////////////
1215/// Returns color-index representing the color.
1216
1218{
1219 if (fIndex == -1)
1220 fIndex = TColor::GetColor(fRGBA[0], fRGBA[1], fRGBA[2]);
1221 return fIndex;
1222}
1223
1224////////////////////////////////////////////////////////////////////////////////
1225/// Returns transparency value.
1226
1228{
1229 return TMath::Nint(100.0*(1.0 - fRGBA[3]/255.0));
1230}
1231
1232////////////////////////////////////////////////////////////////////////////////
1233/// Set color with Int_t values.
1234
1236{
1237 fRGBA[0] = r;
1238 fRGBA[1] = g;
1239 fRGBA[2] = b;
1240 fRGBA[3] = a;
1241 fIndex = -1;
1242}
1243
1244////////////////////////////////////////////////////////////////////////////////
1245/// Set color with Float_t values.
1246
1248{
1249 fRGBA[0] = (UChar_t)(255*r);
1250 fRGBA[1] = (UChar_t)(255*g);
1251 fRGBA[2] = (UChar_t)(255*b);
1252 fRGBA[3] = (UChar_t)(255*a);
1253 fIndex = -1;
1254}
1255
1256////////////////////////////////////////////////////////////////////////////////
1257/// Set color by color-index. Alpha is not changed.
1258/// If color_index is not valid, color is set to magenta.
1259
1261{
1262 TColor* c = gROOT->GetColor(color_index);
1263 if (c)
1264 {
1265 fRGBA[0] = (UChar_t)(255*c->GetRed());
1266 fRGBA[1] = (UChar_t)(255*c->GetGreen());
1267 fRGBA[2] = (UChar_t)(255*c->GetBlue());
1268 fIndex = color_index;
1269 }
1270 else
1271 {
1272 // Set to magenta.
1273 fRGBA[0] = 255;
1274 fRGBA[1] = 0;
1275 fRGBA[2] = 255;
1276 fIndex = -1;
1277 }
1278}
1279
1280////////////////////////////////////////////////////////////////////////////////
1281/// Set color by color-index and alpha from the transparency.
1282/// If color_index is not valid, color is set to magenta.
1283
1284void TGLColor::SetColor(Color_t color_index, Char_t transparency)
1285{
1286 UChar_t alpha = (255*(100 - transparency))/100;
1287
1288 TColor* c = gROOT->GetColor(color_index);
1289 if (c)
1290 {
1291 fRGBA[0] = (UChar_t)(255*c->GetRed());
1292 fRGBA[1] = (UChar_t)(255*c->GetGreen());
1293 fRGBA[2] = (UChar_t)(255*c->GetBlue());
1294 fRGBA[3] = alpha;
1295 fIndex = color_index;
1296 }
1297 else
1298 {
1299 // Set to magenta.
1300 fRGBA[0] = 255;
1301 fRGBA[1] = 0;
1302 fRGBA[2] = 255;
1303 fRGBA[3] = alpha;
1304 fIndex = -1;
1305 return;
1306 }
1307}
1308
1309////////////////////////////////////////////////////////////////////////////////
1310/// Set alpha from the transparency.
1311
1313{
1314 fRGBA[3] = (255*(100 - transparency))/100;
1315}
1316
1317////////////////////////////////////////////////////////////////////////////////
1318/// Return string describing the color.
1319
1321{
1322 return TString::Format("rgba:%02hhx/%02hhx/%02hhx/%02hhx",
1323 fRGBA[0], fRGBA[1], fRGBA[2], fRGBA[3]);
1324}
1325
1326
1327/** \class TGLColorSet
1328\ingroup opengl
1329Class encapsulating a set of colors used throughout standard rendering.
1330*/
1331
1333
1334////////////////////////////////////////////////////////////////////////////////
1335/// Constructor. Sets default for dark background.
1336
1338{
1340}
1341
1342////////////////////////////////////////////////////////////////////////////////
1343/// Copy constructor
1344
1346{
1347 fBackground = s.fBackground;
1348 fForeground = s.fForeground;
1349 fOutline = s.fOutline;
1350 fMarkup = s.fMarkup;
1351 for (Int_t i = 0; i < 5; ++i)
1352 fSelection[i] = s.fSelection[i];
1353}
1354
1355////////////////////////////////////////////////////////////////////////////////
1356/// Assignment operator.
1357
1359{
1360 fBackground = s.fBackground;
1361 fForeground = s.fForeground;
1362 fOutline = s.fOutline;
1363 fMarkup = s.fMarkup;
1364 for (Int_t i = 0; i < 5; ++i)
1365 fSelection[i] = s.fSelection[i];
1366 return *this;
1367}
1368
1369////////////////////////////////////////////////////////////////////////////////
1370/// Set defaults for dark (black) background.
1371
1373{
1374 fBackground .SetColor(0, 0, 0);
1375 fForeground .SetColor(255, 255, 255);
1376 fOutline .SetColor(240, 255, 240);
1377 fMarkup .SetColor(200, 200, 200);
1378
1379 fSelection[0].SetColor( 0, 0, 0);
1380 fSelection[1].SetColor(255, 220, 220);
1381 fSelection[2].SetColor(255, 220, 220);
1382 fSelection[3].SetColor(200, 200, 255);
1383 fSelection[4].SetColor(200, 200, 255);
1384}
1385
1386////////////////////////////////////////////////////////////////////////////////
1387/// Set defaults for light (white) background.
1388
1390{
1391 fBackground .SetColor(255, 255, 255);
1392 fForeground .SetColor(0, 0, 0);
1393 fOutline .SetColor(0, 0, 0);
1394 fMarkup .SetColor(55, 55, 55);
1395
1396 fSelection[0].SetColor(0, 0, 0);
1397 fSelection[1].SetColor(200, 100, 100);
1398 fSelection[2].SetColor(200, 100, 100);
1399 fSelection[3].SetColor(100, 100, 200);
1400 fSelection[4].SetColor(100, 100, 200);
1401}
1402
1403
1404/** \class TGLUtil
1405\ingroup opengl
1406Wrapper class for various misc static functions - error checking, draw helpers etc.
1407*/
1408
1410
1412UInt_t TGLUtil::fgDrawQuality = fgDefaultDrawQuality;
1414
1419
1423
1424const UChar_t TGLUtil::fgRed[4] = { 230, 0, 0, 255 };
1425const UChar_t TGLUtil::fgGreen[4] = { 0, 230, 0, 255 };
1426const UChar_t TGLUtil::fgBlue[4] = { 0, 0, 230, 255 };
1427const UChar_t TGLUtil::fgYellow[4] = { 210, 210, 0, 255 };
1428const UChar_t TGLUtil::fgWhite[4] = { 255, 255, 255, 255 };
1429const UChar_t TGLUtil::fgGrey[4] = { 128, 128, 128, 100 };
1430
1431#ifndef CALLBACK
1432#define CALLBACK
1433#endif
1434
1435extern "C"
1436{
1437#if defined(__APPLE_CC__) && __APPLE_CC__ > 4000 && __APPLE_CC__ < 5450 && !defined(__INTEL_COMPILER)
1438 typedef GLvoid (*tessfuncptr_t)(...);
1439#elif defined(__linux__) || defined(__FreeBSD__) || defined( __OpenBSD__ ) || defined(__sun) || defined (__CYGWIN__) || defined (__APPLE__)
1440 typedef GLvoid (*tessfuncptr_t)();
1441#elif defined (WIN32)
1442 typedef GLvoid (CALLBACK *tessfuncptr_t)();
1443#else
1444 #error "Error - need to define type tessfuncptr_t for this platform/compiler"
1445#endif
1446}
1447
1448namespace
1449{
1450
1451class TGLTesselatorWrap
1452{
1453protected:
1454
1455public:
1456 GLUtesselator *fTess;
1457
1458 TGLTesselatorWrap(tessfuncptr_t vertex_func) : fTess(0)
1459 {
1460 fTess = gluNewTess();
1461 if (!fTess)
1462 throw std::bad_alloc();
1463
1464#if defined(__GNUC__) && __GNUC__ >= 8
1465#pragma GCC diagnostic push
1466#pragma GCC diagnostic ignored "-Wcast-function-type"
1467#endif
1468
1469 gluTessCallback(fTess, (GLenum)GLU_BEGIN, (tessfuncptr_t) glBegin);
1470 gluTessCallback(fTess, (GLenum)GLU_END, (tessfuncptr_t) glEnd);
1471 gluTessCallback(fTess, (GLenum)GLU_VERTEX, vertex_func);
1472
1473#if defined(__GNUC__) && __GNUC__ >= 8
1474#pragma GCC diagnostic pop
1475#endif
1476
1477 }
1478
1479 virtual ~TGLTesselatorWrap()
1480 {
1481 if (fTess)
1482 gluDeleteTess(fTess);
1483 }
1484};
1485
1486}
1487
1488////////////////////////////////////////////////////////////////////////////////
1489/// Returns a tesselator for direct drawing when using 3-vertices with
1490/// single precision.
1491
1493{
1494
1495#if defined(__GNUC__) && __GNUC__ >= 8
1496#pragma GCC diagnostic push
1497#pragma GCC diagnostic ignored "-Wcast-function-type"
1498#endif
1499
1500 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex3fv);
1501
1502#if defined(__GNUC__) && __GNUC__ >= 8
1503#pragma GCC diagnostic pop
1504#endif
1505
1506 return singleton.fTess;
1507}
1508
1509////////////////////////////////////////////////////////////////////////////////
1510/// Returns a tesselator for direct drawing when using 4-vertices with
1511/// single precision.
1512
1514{
1515
1516#if defined(__GNUC__) && __GNUC__ >= 8
1517#pragma GCC diagnostic push
1518#pragma GCC diagnostic ignored "-Wcast-function-type"
1519#endif
1520
1521 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex4fv);
1522
1523#if defined(__GNUC__) && __GNUC__ >= 8
1524#pragma GCC diagnostic pop
1525#endif
1526
1527 return singleton.fTess;
1528}
1529
1530////////////////////////////////////////////////////////////////////////////////
1531/// Returns a tesselator for direct drawing when using 3-vertices with
1532/// double precision.
1533
1535{
1536
1537#if defined(__GNUC__) && __GNUC__ >= 8
1538#pragma GCC diagnostic push
1539#pragma GCC diagnostic ignored "-Wcast-function-type"
1540#endif
1541
1542 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex3dv);
1543
1544#if defined(__GNUC__) && __GNUC__ >= 8
1545#pragma GCC diagnostic pop
1546#endif
1547
1548 return singleton.fTess;
1549}
1550
1551////////////////////////////////////////////////////////////////////////////////
1552/// Returns a tesselator for direct drawing when using 4-vertices with
1553/// double precision.
1554
1556{
1557
1558#if defined(__GNUC__) && __GNUC__ >= 8
1559#pragma GCC diagnostic push
1560#pragma GCC diagnostic ignored "-Wcast-function-type"
1561#endif
1562
1563 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex4dv);
1564
1565#if defined(__GNUC__) && __GNUC__ >= 8
1566#pragma GCC diagnostic pop
1567#endif
1568
1569 return singleton.fTess;
1570}
1571
1572////////////////////////////////////////////////////////////////////////////////
1573/// Initialize globals that require other libraries to be initialized.
1574/// This is called from TGLWidget creation function.
1575
1577{
1578 static Bool_t init_done = kFALSE;
1579 if (init_done) return;
1580 init_done = kTRUE;
1581
1582 fgScreenScalingFactor = gVirtualX->GetOpenGLScalingFactor();
1583
1584 if (strcmp(gEnv->GetValue("OpenGL.PointLineScalingFactor", "native"), "native") == 0)
1585 {
1587 }
1588 else
1589 {
1590 fgPointLineScalingFactor = gEnv->GetValue("OpenGL.PointLineScalingFactor", 1.0);
1591 }
1592
1593 fgPickingRadius = TMath::Nint(gEnv->GetValue("OpenGL.PickingRadius", 3.0) * TMath::Sqrt(fgScreenScalingFactor));
1594}
1595
1596////////////////////////////////////////////////////////////////////////////////
1597///static: get draw quality
1598
1600{
1601 return fgDrawQuality;
1602}
1603
1604////////////////////////////////////////////////////////////////////////////////
1605///static: set draw quality
1606
1608{
1609 fgDrawQuality = dq;
1610}
1611
1612////////////////////////////////////////////////////////////////////////////////
1613///static: reset draw quality
1614
1616{
1618}
1619
1620////////////////////////////////////////////////////////////////////////////////
1621///static: get default draw quality
1622
1624{
1625 return fgDefaultDrawQuality;
1626}
1627
1628////////////////////////////////////////////////////////////////////////////////
1629///static: set default draw quality
1630
1632{
1634}
1635
1636////////////////////////////////////////////////////////////////////////////////
1637/// Check current GL error state, outputting details via ROOT
1638/// Error method if one
1639
1641{
1642 GLenum errCode;
1643 const GLubyte *errString;
1644
1645 if ((errCode = glGetError()) != GL_NO_ERROR) {
1646 errString = gluErrorString(errCode);
1647 if (loc) {
1648 Error(loc, "GL Error %s", (const char *)errString);
1649 } else {
1650 Error("TGLUtil::CheckError", "GL Error %s", (const char *)errString);
1651 }
1652 }
1653 return errCode;
1654}
1655
1656/******************************************************************************/
1657// Color wrapping functions
1658/******************************************************************************/
1659
1660////////////////////////////////////////////////////////////////////////////////
1661/// Prevent further color changes.
1662
1664{
1665 return ++fgColorLockCount;
1666}
1667
1668////////////////////////////////////////////////////////////////////////////////
1669/// Allow color changes.
1670
1672{
1673 if (fgColorLockCount)
1675 else
1676 Error("TGLUtil::UnlockColor", "fgColorLockCount already 0.");
1677 return fgColorLockCount;
1678}
1679
1680////////////////////////////////////////////////////////////////////////////////
1681/// Returns true if color lock-count is greater than 0.
1682
1684{
1685 return fgColorLockCount > 0;
1686}
1687
1688////////////////////////////////////////////////////////////////////////////////
1689/// Set color from TGLColor.
1690
1691void TGLUtil::Color(const TGLColor& color)
1692{
1693 if (fgColorLockCount == 0) glColor4ubv(color.CArr());
1694}
1695
1696////////////////////////////////////////////////////////////////////////////////
1697/// Set color from TGLColor and alpha value.
1698
1699void TGLUtil::ColorAlpha(const TGLColor& color, UChar_t alpha)
1700{
1701 if (fgColorLockCount == 0)
1702 {
1703 glColor4ub(color.GetRed(), color.GetGreen(), color.GetBlue(), alpha);
1704 }
1705}
1706
1707////////////////////////////////////////////////////////////////////////////////
1708/// Set color from TGLColor and alpha value.
1709
1710void TGLUtil::ColorAlpha(const TGLColor& color, Float_t alpha)
1711{
1712 if (fgColorLockCount == 0)
1713 {
1714 glColor4ub(color.GetRed(), color.GetGreen(), color.GetBlue(), (UChar_t)(255*alpha));
1715 }
1716}
1717
1718////////////////////////////////////////////////////////////////////////////////
1719/// Set color from color_index and GL-style alpha (default 1).
1720
1721void TGLUtil::ColorAlpha(Color_t color_index, Float_t alpha)
1722{
1723 if (fgColorLockCount == 0) {
1724 if (color_index < 0)
1725 color_index = 1;
1726 TColor* c = gROOT->GetColor(color_index);
1727 if (c)
1728 glColor4f(c->GetRed(), c->GetGreen(), c->GetBlue(), alpha);
1729 }
1730}
1731
1732////////////////////////////////////////////////////////////////////////////////
1733/// Set color from color_index and ROOT-style transparency (default 0).
1734
1735void TGLUtil::ColorTransparency(Color_t color_index, Char_t transparency)
1736{
1737 if (fgColorLockCount == 0) {
1738 if (color_index < 0)
1739 color_index = 1;
1740 TColor* c = gROOT->GetColor(color_index);
1741 if (c)
1742 glColor4f(c->GetRed(), c->GetGreen(), c->GetBlue(), 1.0f - 0.01f*transparency);
1743 }
1744}
1745
1746////////////////////////////////////////////////////////////////////////////////
1747/// Wrapper for glColor3ub.
1748
1750{
1751 if (fgColorLockCount == 0) glColor3ub(r, g, b);
1752}
1753
1754////////////////////////////////////////////////////////////////////////////////
1755/// Wrapper for glColor4ub.
1756
1758{
1759 if (fgColorLockCount == 0) glColor4ub(r, g, b, a);
1760}
1761
1762////////////////////////////////////////////////////////////////////////////////
1763/// Wrapper for glColor3ubv.
1764
1766{
1767 if (fgColorLockCount == 0) glColor3ubv(rgb);
1768}
1769
1770////////////////////////////////////////////////////////////////////////////////
1771/// Wrapper for glColor4ubv.
1772
1774{
1775 if (fgColorLockCount == 0) glColor4ubv(rgba);
1776}
1777
1778////////////////////////////////////////////////////////////////////////////////
1779/// Wrapper for glColor3f.
1780
1782{
1783 if (fgColorLockCount == 0) glColor3f(r, g, b);
1784}
1785
1786////////////////////////////////////////////////////////////////////////////////
1787/// Wrapper for glColor4f.
1788
1790{
1791 if (fgColorLockCount == 0) glColor4f(r, g, b, a);
1792}
1793
1794////////////////////////////////////////////////////////////////////////////////
1795/// Wrapper for glColor3fv.
1796
1798{
1799 if (fgColorLockCount == 0) glColor3fv(rgb);
1800}
1801
1802////////////////////////////////////////////////////////////////////////////////
1803/// Wrapper for glColor4fv.
1804
1806{
1807 if (fgColorLockCount == 0) glColor4fv(rgba);
1808}
1809
1810/******************************************************************************/
1811// Coordinate conversion and extra scaling (needed for osx retina)
1812/******************************************************************************/
1813
1814////////////////////////////////////////////////////////////////////////////////
1815/// Convert from point/screen coordinates to GL viewport coordinates.
1816
1818{
1819 if (fgScreenScalingFactor != 1.0)
1820 {
1823 }
1824}
1825
1826////////////////////////////////////////////////////////////////////////////////
1827/// Convert from point/screen coordinates to GL viewport coordinates.
1828
1830{
1831 if (fgScreenScalingFactor != 1.0)
1832 {
1837 }
1838}
1839
1840////////////////////////////////////////////////////////////////////////////////
1841/// Returns scaling factor between screen points and GL viewport pixels.
1842/// This is what is returned by gVirtualX->GetOpenGLScalingFactor() but is
1843/// cached here to avoid a virtual function call as it is used quite often in
1844/// TGLPhysical shape when drawing the selection highlight.
1845
1847{
1848 return fgScreenScalingFactor;
1849}
1850
1851////////////////////////////////////////////////////////////////////////////////
1852/// Return extra scaling factor for points and lines.
1853/// By default this is set to the same value as ScreenScalingFactor to keep
1854/// the same appearance. To override use rootrc entry, e.g.:
1855/// OpenGL.PointLineScalingFactor: 1.0
1856
1858{
1860}
1861
1862////////////////////////////////////////////////////////////////////////////////
1863/// Returns picking radius.
1864
1866{
1867 return fgPickingRadius;
1868}
1869
1870/******************************************************************************/
1871// Control for scaling of point-size and line-width.
1872/******************************************************************************/
1873
1874////////////////////////////////////////////////////////////////////////////////
1875/// Get global point-size scale.
1876
1878{
1879 return fgPointSizeScale;
1880}
1881
1882////////////////////////////////////////////////////////////////////////////////
1883/// Set global point-size scale.
1884
1886{
1887 fgPointSizeScale = scale;
1888}
1889
1890////////////////////////////////////////////////////////////////////////////////
1891/// Returns global line-width scale.
1892
1894{
1895 return fgLineWidthScale;
1896}
1897
1898////////////////////////////////////////////////////////////////////////////////
1899/// Set global line-width scale.
1900
1902{
1903 fgLineWidthScale = scale;
1904}
1905
1906////////////////////////////////////////////////////////////////////////////////
1907/// Set the point-size, taking the global scaling into account.
1908/// Wrapper for glPointSize.
1909
1911{
1913 glPointSize(fgPointSize);
1914}
1915
1916////////////////////////////////////////////////////////////////////////////////
1917/// Set the line-width, taking the global scaling into account.
1918/// Wrapper for glLineWidth.
1919
1921{
1923 glLineWidth(fgLineWidth);
1924}
1925
1926////////////////////////////////////////////////////////////////////////////////
1927/// Get the point-size, taking the global scaling into account.
1928
1930{
1931 return fgPointSize;
1932}
1933
1934////////////////////////////////////////////////////////////////////////////////
1935/// Get the line-width, taking the global scaling into account.
1936
1938{
1939 return fgLineWidth;
1940}
1941
1942/******************************************************************************/
1943// Rendering of polymarkers and lines from logical-shapes.
1944/******************************************************************************/
1945
1947{
1948 // Extend pick region for large point-sizes or line-widths.
1949
1950 glMatrixMode(GL_PROJECTION);
1951 glPushMatrix();
1952 Float_t pm[16];
1953 glGetFloatv(GL_PROJECTION_MATRIX, pm);
1954 for (Int_t i=0; i<=12; i+=4) {
1955 pm[i] *= scale; pm[i+1] *= scale;
1956 }
1957 glLoadMatrixf(pm);
1958 glMatrixMode(GL_MODELVIEW);
1959}
1960
1962{
1963 // End extension of the pick region.
1964
1965 glMatrixMode(GL_PROJECTION);
1966 glPopMatrix();
1967 glMatrixMode(GL_MODELVIEW);
1968}
1969
1970////////////////////////////////////////////////////////////////////////////////
1971/// Render polymarkers at points specified by p-array.
1972/// Supports point and cross-like styles.
1973
1975 Float_t* p, Int_t n,
1976 Int_t pick_radius, Bool_t selection,
1977 Bool_t sec_selection)
1978{
1979 if (n == 0) return;
1980
1981 glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT | GL_LINE_BIT);
1982
1983 glDisable(GL_LIGHTING);
1985
1986 Int_t s = marker.GetMarkerStyle();
1987 if (s == 2 || s == 3 || s == 5 || s == 28)
1988 RenderCrosses(marker, p, n, sec_selection);
1989 else
1990 RenderPoints(marker, p, n, pick_radius, selection, sec_selection);
1991
1992 glPopAttrib();
1993}
1994
1995////////////////////////////////////////////////////////////////////////////////
1996/// Render polymarkers at points specified by p-array.
1997/// Supports point and cross-like styles.
1998/// Color is set externally. Lighting is disabled externally.
1999
2000void TGLUtil::RenderPolyMarkers(const TAttMarker &marker, const std::vector<Double_t> &points,
2001 Double_t dX, Double_t dY, Double_t dZ)
2002{
2003 const Int_t s = marker.GetMarkerStyle();
2004 if (s == 2 || s == 3 || s == 5 || s == 28)
2005 RenderCrosses(marker, points, dX, dY, dZ);
2006 else
2007 RenderPoints(marker, points);
2008}
2009
2010////////////////////////////////////////////////////////////////////////////////
2011/// Render markers as circular or square points.
2012/// Color is never changed.
2013
2015 Float_t* op, Int_t n,
2016 Int_t pick_radius, Bool_t selection,
2017 Bool_t sec_selection)
2018{
2019 Int_t style = marker.GetMarkerStyle();
2020 Float_t size = 5*marker.GetMarkerSize();
2021 if (style == 4 || style == 20 || style == 24)
2022 {
2023 glEnable(GL_POINT_SMOOTH);
2024 if (style == 4 || style == 24) {
2025 glEnable(GL_BLEND);
2026 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2027 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
2028 }
2029 }
2030 else
2031 {
2032 glDisable(GL_POINT_SMOOTH);
2033 if (style == 1) size = 1;
2034 else if (style == 6) size = 2;
2035 else if (style == 7) size = 3;
2036 }
2038
2039 // During selection extend picking region for large point-sizes.
2040 Bool_t changePM = selection && PointSize() > pick_radius;
2041 if (changePM)
2042 BeginExtendPickRegion((Float_t) pick_radius / PointSize());
2043
2044 Float_t* p = op;
2045 if (sec_selection)
2046 {
2047 glPushName(0);
2048 for (Int_t i=0; i<n; ++i, p+=3)
2049 {
2050 glLoadName(i);
2051 glBegin(GL_POINTS);
2052 glVertex3fv(p);
2053 glEnd();
2054 }
2055 glPopName();
2056 }
2057 else
2058 {
2059 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
2060 glVertexPointer(3, GL_FLOAT, 0, p);
2061 glEnableClientState(GL_VERTEX_ARRAY);
2062 { // Circumvent bug in ATI's linux drivers.
2063 Int_t nleft = n;
2064 Int_t ndone = 0;
2065 const Int_t maxChunk = 8192;
2066 while (nleft > maxChunk)
2067 {
2068 glDrawArrays(GL_POINTS, ndone, maxChunk);
2069 nleft -= maxChunk;
2070 ndone += maxChunk;
2071 }
2072 glDrawArrays(GL_POINTS, ndone, nleft);
2073 }
2074 glPopClientAttrib();
2075 }
2076
2077 if (changePM)
2079}
2080
2081////////////////////////////////////////////////////////////////////////////////
2082/// Render markers as circular or square points.
2083/// Color is never changed.
2084
2085void TGLUtil::RenderPoints(const TAttMarker& marker, const std::vector<Double_t> &points)
2086{
2087 const Int_t style = marker.GetMarkerStyle();
2088 Float_t size = 5 * marker.GetMarkerSize();
2089
2090 if (style == 4 || style == 20 || style == 24)
2091 {
2092 glEnable(GL_POINT_SMOOTH);
2093 if (style == 4 || style == 24) {
2094 glEnable(GL_BLEND);
2095 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2096 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
2097 }
2098 }
2099 else
2100 {
2101 glDisable(GL_POINT_SMOOTH);
2102 if (style == 1) size = 1;
2103 else if (style == 6) size = 2;
2104 else if (style == 7) size = 3;
2105 }
2106
2107 glPointSize(size);
2108
2109 glVertexPointer(3, GL_DOUBLE, 0, &points[0]);
2110 glEnableClientState(GL_VERTEX_ARRAY);
2111
2112 // Circumvent bug in ATI's linux drivers.
2113 Int_t nleft = points.size() / 3;
2114 Int_t ndone = 0;
2115 const Int_t maxChunk = 8192;
2116 while (nleft > maxChunk)
2117 {
2118 glDrawArrays(GL_POINTS, ndone, maxChunk);
2119 nleft -= maxChunk;
2120 ndone += maxChunk;
2121 }
2122
2123 if (nleft > 0)
2124 glDrawArrays(GL_POINTS, ndone, nleft);
2125
2126 glDisableClientState(GL_VERTEX_ARRAY);
2127 glPointSize(1.f);
2128}
2129
2130////////////////////////////////////////////////////////////////////////////////
2131/// Render markers as crosses.
2132/// Color is never changed.
2133
2135 Float_t* op, Int_t n,
2136 Bool_t sec_selection)
2137{
2138 if (marker.GetMarkerStyle() == 28)
2139 {
2140 glEnable(GL_BLEND);
2141 glEnable(GL_LINE_SMOOTH);
2143 }
2144 else
2145 {
2146 glDisable(GL_LINE_SMOOTH);
2148 }
2149
2150 // cross dim
2151 const Float_t d = 2*marker.GetMarkerSize();
2152 Float_t* p = op;
2153 if (sec_selection)
2154 {
2155 glPushName(0);
2156 for (Int_t i=0; i<n; ++i, p+=3)
2157 {
2158 glLoadName(i);
2159 glBegin(GL_LINES);
2160 glVertex3f(p[0]-d, p[1], p[2]); glVertex3f(p[0]+d, p[1], p[2]);
2161 glVertex3f(p[0], p[1]-d, p[2]); glVertex3f(p[0], p[1]+d, p[2]);
2162 glVertex3f(p[0], p[1], p[2]-d); glVertex3f(p[0], p[1], p[2]+d);
2163 glEnd();
2164 }
2165 glPopName();
2166 }
2167 else
2168 {
2169 glBegin(GL_LINES);
2170 for (Int_t i=0; i<n; ++i, p+=3)
2171 {
2172 glVertex3f(p[0]-d, p[1], p[2]); glVertex3f(p[0]+d, p[1], p[2]);
2173 glVertex3f(p[0], p[1]-d, p[2]); glVertex3f(p[0], p[1]+d, p[2]);
2174 glVertex3f(p[0], p[1], p[2]-d); glVertex3f(p[0], p[1], p[2]+d);
2175 }
2176 glEnd();
2177 }
2178
2179 // Anti-flickering -- when crosses get too small they
2180 // appear / disappear randomly.
2181 {
2182 glDisable(GL_POINT_SMOOTH);
2184
2185 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
2186 glVertexPointer(3, GL_FLOAT, 0, op);
2187 glEnableClientState(GL_VERTEX_ARRAY);
2188 { // Circumvent bug in ATI's linux drivers.
2189 Int_t nleft = n;
2190 Int_t ndone = 0;
2191 const Int_t maxChunk = 8192;
2192 while (nleft > maxChunk)
2193 {
2194 glDrawArrays(GL_POINTS, ndone, maxChunk);
2195 nleft -= maxChunk;
2196 ndone += maxChunk;
2197 }
2198 glDrawArrays(GL_POINTS, ndone, nleft);
2199 }
2200 glPopClientAttrib();
2201 }
2202}
2203
2204////////////////////////////////////////////////////////////////////////////////
2205/// Render markers as crosses.
2206/// Color is never changed.
2207
2208void TGLUtil::RenderCrosses(const TAttMarker& marker, const std::vector<Double_t> &points,
2209 Double_t dX, Double_t dY, Double_t dZ)
2210{
2211 if (marker.GetMarkerStyle() == 28)
2212 {
2213 glEnable(GL_BLEND);
2214 glEnable(GL_LINE_SMOOTH);
2215 glLineWidth(2.f);
2216 }
2217 else
2218 {
2219 glDisable(GL_LINE_SMOOTH);
2220 glLineWidth(1.f);
2221 }
2222
2223 typedef std::vector<Double_t>::size_type size_type;
2224
2225 glBegin(GL_LINES);
2226
2227 for (size_type i = 0; i < points.size(); i += 3) {
2228 const Double_t *p = &points[i];
2229 glVertex3f(p[0] - dX, p[1], p[2]); glVertex3f(p[0] + dX, p[1], p[2]);
2230 glVertex3f(p[0], p[1] - dY, p[2]); glVertex3f(p[0], p[1] + dY, p[2]);
2231 glVertex3f(p[0], p[1], p[2] - dZ); glVertex3f(p[0], p[1], p[2] + dZ);
2232 }
2233
2234 glEnd();
2235
2236 if (marker.GetMarkerStyle() == 28) {
2237 glDisable(GL_LINE_SMOOTH);
2238 glDisable(GL_BLEND);
2239 glLineWidth(1.f);
2240 }
2241}
2242
2243////////////////////////////////////////////////////////////////////////////////
2244/// Render poly-line as specified by the p-array.
2245
2246void TGLUtil::RenderPolyLine(const TAttLine& aline, Char_t transp,
2247 Float_t* p, Int_t n,
2248 Int_t pick_radius, Bool_t selection)
2249{
2250 if (n == 0) return;
2251
2252 BeginAttLine(aline, transp, pick_radius, selection);
2253
2254 Float_t* tp = p;
2255 glBegin(GL_LINE_STRIP);
2256 for (Int_t i=0; i<n; ++i, tp+=3)
2257 glVertex3fv(tp);
2258 glEnd();
2259
2260 EndAttLine(pick_radius, selection);
2261}
2262
2263////////////////////////////////////////////////////////////////////////////////
2264/// Setup drawing parameters according to passed TAttLine.
2265
2266void TGLUtil::BeginAttLine(const TAttLine& aline, Char_t transp,
2267 Int_t pick_radius, Bool_t selection)
2268{
2269 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
2270
2271 glDisable(GL_LIGHTING);
2274 if (aline.GetLineStyle() > 1)
2275 {
2276 // Int_t fac = 1;
2277 UShort_t pat = 0xffff;
2278 switch (aline.GetLineStyle()) {
2279 case 2: pat = 0x3333; break;
2280 case 3: pat = 0x5555; break;
2281 case 4: pat = 0xf040; break;
2282 case 5: pat = 0xf4f4; break;
2283 case 6: pat = 0xf111; break;
2284 case 7: pat = 0xf0f0; break;
2285 case 8: pat = 0xff11; break;
2286 case 9: pat = 0x3fff; break;
2287 case 10: pat = 0x08ff; /* fac = 2; */ break;
2288 }
2289
2290 glLineStipple(1, pat);
2291 glEnable(GL_LINE_STIPPLE);
2292 }
2293
2294 // During selection extend picking region for large line-widths.
2295 if (selection && TGLUtil::LineWidth() > pick_radius)
2297}
2298
2299////////////////////////////////////////////////////////////////////////////////
2300/// Restore previous line drawing state.
2301
2302void TGLUtil::EndAttLine(Int_t pick_radius, Bool_t selection)
2303{
2304 if (selection && TGLUtil::LineWidth() > pick_radius)
2306
2307 glPopAttrib();
2308}
2309
2310/******************************************************************************/
2311// Rendering atoms used by TGLViewer / TGScene.
2312/******************************************************************************/
2313
2314////////////////////////////////////////////////////////////////////////////////
2315/// Set basic draw colors from 4 component 'rgba'
2316/// Used by other TGLUtil drawing routines
2317///
2318/// Sets basic (unlit) color - glColor
2319/// and also GL materials (see OpenGL docs) thus:
2320///
2321/// diffuse : rgba
2322/// ambient : 0.0 0.0 0.0 1.0
2323/// specular : 0.6 0.6 0.6 1.0
2324/// emission : rgba/4.0
2325/// shininess: 60.0
2326///
2327/// emission is set so objects with no lights (but lighting still enabled)
2328/// are partially visible
2329
2331{
2332
2333 // Util function to setup GL color for both unlit and lit material
2334 Float_t rgba[4] = {rgbai[0]/255.f, rgbai[1]/255.f, rgbai[2]/255.f, rgbai[3]/255.f};
2335 Float_t ambient[4] = {0.0, 0.0, 0.0, 1.0};
2336 Float_t specular[4] = {0.6, 0.6, 0.6, 1.0};
2337 Float_t emission[4] = {rgba[0]/4.f, rgba[1]/4.f, rgba[2]/4.f, rgba[3]};
2338
2339 glColor4fv(rgba);
2340 glMaterialfv(GL_FRONT, GL_DIFFUSE, rgba);
2341 glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
2342 glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
2343 glMaterialfv(GL_FRONT, GL_EMISSION, emission);
2344 glMaterialf(GL_FRONT, GL_SHININESS, 60.0);
2345}
2346
2347////////////////////////////////////////////////////////////////////////////////
2348/// Draw sphere, centered on vertex 'position', with radius 'radius',
2349/// color 'rgba'
2350
2351void TGLUtil::DrawSphere(const TGLVertex3 & position, Double_t radius,
2352 const UChar_t rgba[4])
2353{
2354 static TGLQuadric quad;
2355 SetDrawColors(rgba);
2356 glPushMatrix();
2357 glTranslated(position.X(), position.Y(), position.Z());
2358 gluSphere(quad.Get(), radius, fgDrawQuality, fgDrawQuality);
2359 glPopMatrix();
2360}
2361
2362////////////////////////////////////////////////////////////////////////////////
2363/// Draw thick line (tube) defined by 'line', with head at end shape
2364/// 'head' - box/arrow/none, (head) size 'size', color 'rgba'
2365
2367 const UChar_t rgba[4])
2368{
2369 DrawLine(line.Start(), line.Vector(), head, size, rgba);
2370}
2371
2372////////////////////////////////////////////////////////////////////////////////
2373/// Draw thick line (tube) running from 'start', length 'vector',
2374/// with head at end of shape 'head' - box/arrow/none,
2375/// (head) size 'size', color 'rgba'
2376
2377void TGLUtil::DrawLine(const TGLVertex3 & start, const TGLVector3 & vector,
2378 ELineHeadShape head, Double_t size, const UChar_t rgba[4])
2379{
2380 static TGLQuadric quad;
2381
2382 // Draw 3D line (tube) with optional head shape
2383 SetDrawColors(rgba);
2384 glPushMatrix();
2385 TGLMatrix local(start, vector);
2386 glMultMatrixd(local.CArr());
2387
2388 Double_t headHeight=0;
2389 if (head == kLineHeadNone) {
2390 headHeight = 0.0;
2391 } else if (head == kLineHeadArrow) {
2392 headHeight = size*2.0;
2393 } else if (head == kLineHeadBox) {
2394 headHeight = size*1.4;
2395 }
2396
2397 // Line (tube) component
2398 gluCylinder(quad.Get(), 0.25*size, 0.25*size, vector.Mag() - headHeight, fgDrawQuality, 1);
2399 gluQuadricOrientation(quad.Get(), (GLenum)GLU_INSIDE);
2400 gluDisk(quad.Get(), 0.0, 0.25*size, fgDrawQuality, 1);
2401
2402 glTranslated(0.0, 0.0, vector.Mag() - headHeight); // Shift down local Z to end of line
2403
2404 if (head == kLineHeadNone) {
2405 // Cap end of line
2406 gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
2407 gluDisk(quad.Get(), 0.0, size/4.0, fgDrawQuality, 1);
2408 }
2409 else if (head == kLineHeadArrow) {
2410 // Arrow base / end line cap
2411 gluDisk(quad.Get(), 0.0, size, fgDrawQuality, 1);
2412 // Arrow cone
2413 gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
2414 gluCylinder(quad.Get(), size, 0.0, headHeight, fgDrawQuality, 1);
2415 } else if (head == kLineHeadBox) {
2416 // Box
2417 // TODO: Drawing box should be simpler - maybe make
2418 // a static helper which BB + others use.
2419 // Single face tesselation - ugly lighting
2420 gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
2421 TGLBoundingBox box(TGLVertex3(-size*.7, -size*.7, 0.0),
2422 TGLVertex3(size*.7, size*.7, headHeight));
2423 box.Draw(kTRUE);
2424 }
2425 glPopMatrix();
2426}
2427
2428////////////////////////////////////////////////////////////////////////////////
2429/// Draw ring, centered on 'center', lying on plane defined by 'center' & 'normal'
2430/// of outer radius 'radius', color 'rgba'
2431
2432void TGLUtil::DrawRing(const TGLVertex3 & center, const TGLVector3 & normal,
2433 Double_t radius, const UChar_t rgba[4])
2434{
2435 static TGLQuadric quad;
2436
2437 // Draw a ring, round vertex 'center', lying on plane defined by 'normal' vector
2438 // Radius defines the outer radius
2440
2441 Double_t outer = radius;
2442 Double_t width = radius*0.05;
2443 Double_t inner = outer - width;
2444
2445 // Shift into local system, looking down 'normal' vector, origin at center
2446 glPushMatrix();
2447 TGLMatrix local(center, normal);
2448 glMultMatrixd(local.CArr());
2449
2450 // Shift half width so rings centered over center vertex
2451 glTranslated(0.0, 0.0, -width/2.0);
2452
2453 // Inner and outer faces
2454 gluCylinder(quad.Get(), inner, inner, width, fgDrawQuality, 1);
2455 gluCylinder(quad.Get(), outer, outer, width, fgDrawQuality, 1);
2456
2457 // Top/bottom
2458 gluQuadricOrientation(quad.Get(), (GLenum)GLU_INSIDE);
2459 gluDisk(quad.Get(), inner, outer, fgDrawQuality, 1);
2460 glTranslated(0.0, 0.0, width);
2461 gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
2462 gluDisk(quad.Get(), inner, outer, fgDrawQuality, 1);
2463
2464 glPopMatrix();
2465}
2466
2467/**************************************************************************/
2468
2469////////////////////////////////////////////////////////////////////////////////
2470/// Draw a sphere- marker on world-coordinate 'pos' with pixel
2471/// radius 'radius'. Color argument is optional.
2472
2474 const TGLVertex3 & pos,
2475 Float_t radius,
2476 const UChar_t * rgba)
2477{
2478 static const UChar_t defColor[4] = { 250, 110, 0, 255 }; // Orange
2479
2480 radius = camera.ViewportDeltaToWorld(pos, radius, radius).Mag();
2481 DrawSphere(pos, radius, rgba ? rgba : defColor);
2482
2483}
2484
2485////////////////////////////////////////////////////////////////////////////////
2486/// Draw simple xyz-axes for given bounding-box.
2487
2489 const TGLBoundingBox & bbox,
2490 Int_t axesType)
2491{
2492 if (axesType == kAxesNone)
2493 return;
2494
2495 static const UChar_t axesColors[][4] = {
2496 {128, 0, 0, 255}, // -ive X axis light red
2497 {255, 0, 0, 255}, // +ive X axis deep red
2498 { 0, 128, 0, 255}, // -ive Y axis light green
2499 { 0, 255, 0, 255}, // +ive Y axis deep green
2500 { 0, 0, 128, 255}, // -ive Z axis light blue
2501 { 0, 0, 255, 255} // +ive Z axis deep blue
2502 };
2503
2504 static const UChar_t xyz[][8] = {
2505 {0x44, 0x44, 0x28, 0x10, 0x10, 0x28, 0x44, 0x44},
2506 {0x10, 0x10, 0x10, 0x10, 0x10, 0x28, 0x44, 0x44},
2507 {0x7c, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x7c}
2508 };
2509
2510 // Axes draw at fixed screen size - back project to world
2511 TGLVector3 pixelVector = camera.ViewportDeltaToWorld(bbox.Center(), 1, 1);
2512 Double_t pixelSize = pixelVector.Mag();
2513
2514 // Find x/y/z min/max values
2515 Double_t min[3] = { bbox.XMin(), bbox.YMin(), bbox.ZMin() };
2516 Double_t max[3] = { bbox.XMax(), bbox.YMax(), bbox.ZMax() };
2517
2518 for (UInt_t i = 0; i < 3; i++) {
2519 TGLVertex3 start;
2520 TGLVector3 vector;
2521
2522 if (axesType == kAxesOrigin) {
2523 // Through origin axes
2524 start[(i+1)%3] = 0.0;
2525 start[(i+2)%3] = 0.0;
2526 } else {
2527 // Side axes
2528 start[(i+1)%3] = min[(i+1)%3];
2529 start[(i+2)%3] = min[(i+2)%3];
2530 }
2531 vector[(i+1)%3] = 0.0;
2532 vector[(i+2)%3] = 0.0;
2533
2534 // -ive axis?
2535 if (min[i] < 0.0) {
2536 // Runs from origin?
2537 if (max[i] > 0.0) {
2538 start[i] = 0.0;
2539 vector[i] = min[i];
2540 } else {
2541 start[i] = max[i];
2542 vector[i] = min[i] - max[i];
2543 }
2544 DrawLine(start, vector, kLineHeadNone, pixelSize*2.5, axesColors[i*2]);
2545 }
2546 // +ive axis?
2547 if (max[i] > 0.0) {
2548 // Runs from origin?
2549 if (min[i] < 0.0) {
2550 start[i] = 0.0;
2551 vector[i] = max[i];
2552 } else {
2553 start[i] = min[i];
2554 vector[i] = max[i] - min[i];
2555 }
2556 DrawLine(start, vector, kLineHeadNone, pixelSize*2.5, axesColors[i*2 + 1]);
2557 }
2558 }
2559
2560 // Draw origin sphere(s)
2561 if (axesType == kAxesOrigin) {
2562 // Single white origin sphere at 0, 0, 0
2563 DrawSphere(TGLVertex3(0.0, 0.0, 0.0), pixelSize*2.0, fgWhite);
2564 } else {
2565 for (UInt_t j = 0; j < 3; j++) {
2566 if (min[j] <= 0.0 && max[j] >= 0.0) {
2567 TGLVertex3 zero;
2568 zero[j] = 0.0;
2569 zero[(j+1)%3] = min[(j+1)%3];
2570 zero[(j+2)%3] = min[(j+2)%3];
2571 DrawSphere(zero, pixelSize*2.0, axesColors[j*2 + 1]);
2572 }
2573 }
2574 }
2575
2576 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2577
2578 // Labels
2579 Double_t padPixels = 25.0;
2580
2581 glDisable(GL_LIGHTING);
2582 for (UInt_t k = 0; k < 3; k++) {
2583 SetDrawColors(axesColors[k*2+1]);
2584 TGLVertex3 minPos, maxPos;
2585 if (axesType == kAxesOrigin) {
2586 minPos[(k+1)%3] = 0.0;
2587 minPos[(k+2)%3] = 0.0;
2588 } else {
2589 minPos[(k+1)%3] = min[(k+1)%3];
2590 minPos[(k+2)%3] = min[(k+2)%3];
2591 }
2592 maxPos = minPos;
2593 minPos[k] = min[k];
2594 maxPos[k] = max[k];
2595
2596 TGLVector3 axis = maxPos - minPos;
2597 TGLVector3 axisViewport = camera.WorldDeltaToViewport(minPos, axis);
2598
2599 // Skip drawing if viewport projection of axis very small - labels will overlap
2600 // Occurs with orthographic cameras
2601 if (axisViewport.Mag() < 1) {
2602 continue;
2603 }
2604
2605 minPos -= camera.ViewportDeltaToWorld(minPos, padPixels*axisViewport.X()/axisViewport.Mag(),
2606 padPixels*axisViewport.Y()/axisViewport.Mag());
2607 axisViewport = camera.WorldDeltaToViewport(maxPos, -axis);
2608 maxPos -= camera.ViewportDeltaToWorld(maxPos, padPixels*axisViewport.X()/axisViewport.Mag(),
2609 padPixels*axisViewport.Y()/axisViewport.Mag());
2610
2611 DrawNumber(Form("%.0f", min[k]), minPos, kTRUE); // Min value
2612 DrawNumber(Form("%.0f", max[k]), maxPos, kTRUE); // Max value
2613
2614 // Axis name beside max value
2615 TGLVertex3 namePos = maxPos -
2616 camera.ViewportDeltaToWorld(maxPos, padPixels*axisViewport.X()/axisViewport.Mag(),
2617 padPixels*axisViewport.Y()/axisViewport.Mag());
2618 glRasterPos3dv(namePos.CArr());
2619 glBitmap(8, 8, 0.0, 4.0, 0.0, 0.0, xyz[k]); // Axis Name
2620 }
2621}
2622
2623////////////////////////////////////////////////////////////////////////////////
2624/// Draw number in string 'num' via internal 8x8-pixel bitmap on
2625/// vertex 'pos'. If 'center' is true, the number is centered on 'pos'.
2626/// Only numbers, '.', '-' and ' ' are supported.
2627
2629 const TGLVertex3 & pos,
2630 Bool_t center)
2631{
2632 static const UChar_t digits[][8] = {
2633 {0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38},//0
2634 {0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x10, 0x10},//1
2635 {0x7c, 0x44, 0x20, 0x18, 0x04, 0x04, 0x44, 0x38},//2
2636 {0x38, 0x44, 0x04, 0x04, 0x18, 0x04, 0x44, 0x38},//3
2637 {0x04, 0x04, 0x04, 0x04, 0x7c, 0x44, 0x44, 0x44},//4
2638 {0x7c, 0x44, 0x04, 0x04, 0x7c, 0x40, 0x40, 0x7c},//5
2639 {0x7c, 0x44, 0x44, 0x44, 0x7c, 0x40, 0x40, 0x7c},//6
2640 {0x20, 0x20, 0x20, 0x10, 0x08, 0x04, 0x44, 0x7c},//7
2641 {0x38, 0x44, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38},//8
2642 {0x7c, 0x44, 0x04, 0x04, 0x7c, 0x44, 0x44, 0x7c},//9
2643 {0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},//.
2644 {0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00},//-
2645 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} //space
2646 };
2647
2648 Double_t xOffset = 0, yOffset = 0;
2649 if (center)
2650 {
2651 xOffset = 3.5 * num.Length();
2652 yOffset = 4.0;
2653 }
2654
2655 glRasterPos3dv(pos.CArr());
2656 for (Ssiz_t i = 0, e = num.Length(); i < e; ++i) {
2657 if (num[i] == '.') {
2658 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[10]);
2659 } else if (num[i] == '-') {
2660 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[11]);
2661 } else if (num[i] == ' ') {
2662 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[12]);
2663 } else if (num[i] >= '0' && num[i] <= '9') {
2664 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[num[i] - '0']);
2665 }
2666 }
2667}
2668
2669
2670/**************************************************************************/
2671/**************************************************************************/
2672
2673////////////////////////////////////////////////////////////////////////////////
2674/// Constructor - change state only if necessary.
2675
2677 fWhat(what)
2678{
2679 fState = glIsEnabled(fWhat);
2680 fFlip = (fState != state);
2681 if (fFlip)
2682 SetState(state);
2683}
2684
2685////////////////////////////////////////////////////////////////////////////////
2686/// Destructor - reset state if changed.
2687
2689{
2690 if (fFlip)
2692}
2693
2694////////////////////////////////////////////////////////////////////////////////
2695
2697{
2698 if (s)
2699 glEnable(fWhat);
2700 else
2701 glDisable(fWhat);
2702}
2703
2704
2705////////////////////////////////////////////////////////////////////////////////
2706/// Constructor - change state only if necessary.
2707
2709 fWhat(what)
2710{
2711 fFlip = ! glIsEnabled(fWhat) && state;
2712 if (fFlip)
2713 glEnable(fWhat);
2714}
2715
2716////////////////////////////////////////////////////////////////////////////////
2717/// Destructor - reset state if changed.
2718
2720{
2721 if (fFlip)
2722 glDisable(fWhat);
2723}
2724
2725
2726////////////////////////////////////////////////////////////////////////////////
2727
2729 fWhat(what), fState(0), fFlip(kFALSE), fFoo(foo)
2730 {
2731 glGetFloatv(fWhat, &fState);
2732 fFlip = (fState != state);
2733 if (fFlip) fFoo(state);
2734 }
2735
2736////////////////////////////////////////////////////////////////////////////////
2737
2739 {
2740 if (fFlip) fFoo(fState);
2741 }
2742
2743
2744////////////////////////////////////////////////////////////////////////////////
2745/// TGLEnableGuard constructor.
2746
2748 : fCap(cap)
2749{
2750 glEnable(GLenum(fCap));
2751}
2752
2753////////////////////////////////////////////////////////////////////////////////
2754/// TGLEnableGuard destructor.
2755
2757{
2758 glDisable(GLenum(fCap));
2759}
2760
2761////////////////////////////////////////////////////////////////////////////////
2762/// TGLDisableGuard constructor.
2763
2765 : fCap(cap)
2766{
2767 glDisable(GLenum(fCap));
2768}
2769
2770////////////////////////////////////////////////////////////////////////////////
2771/// TGLDisableGuard destructor.
2772
2774{
2775 glEnable(GLenum(fCap));
2776}
2777
2778/** \class TGLSelectionBuffer
2779\ingroup opengl
2780*/
2781
2783
2784////////////////////////////////////////////////////////////////////////////////
2785/// TGLSelectionBuffer constructor.
2786
2788 : fWidth(0), fHeight(0)
2789{
2790}
2791
2792////////////////////////////////////////////////////////////////////////////////
2793/// TGLSelectionBuffer destructor.
2794
2796{
2797}
2798
2799////////////////////////////////////////////////////////////////////////////////
2800/// Read color buffer.
2801
2803{
2804 fWidth = w;
2805 fHeight = h;
2806 fBuffer.resize(w * h * 4);
2807 glPixelStorei(GL_PACK_ALIGNMENT, 1);
2808 glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, &fBuffer[0]);
2809}
2810
2811////////////////////////////////////////////////////////////////////////////////
2812/// Read color buffer.
2813
2815{
2816 fWidth = w;
2817 fHeight = h;
2818 fBuffer.resize(w * h * 4);
2819 glPixelStorei(GL_PACK_ALIGNMENT, 1);
2820 glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, &fBuffer[0]);
2821}
2822
2823////////////////////////////////////////////////////////////////////////////////
2824/// Get pixel color.
2825
2827{
2828 if (px < 0)
2829 px = 0;
2830 if (py < 0)
2831 py = 0;
2832
2833 if (UInt_t(px * fWidth * 4 + py * 4) > fBuffer.size())
2834 return &fBuffer[0];
2835
2836 return &fBuffer[px * fWidth * 4 + py * 4];
2837}
2838
2839namespace Rgl {
2840
2841const Float_t gRedEmission[] = {1.f, 0.f, 0.f, 1.f};
2842const Float_t gGreenEmission[] = {0.f, 1.f, 0.f, 1.f};
2843const Float_t gBlueEmission[] = {0.f, 0.f, 1.f, 1.f};
2844const Float_t gOrangeEmission[] = {1.f, 0.4f, 0.f, 1.f};
2845const Float_t gWhiteEmission[] = {1.f, 1.f, 1.f, 1.f};
2846const Float_t gGrayEmission[] = {0.3f,0.3f, 0.3f,1.f};
2847const Float_t gNullEmission[] = {0.f, 0.f, 0.f, 1.f};
2848
2849namespace {
2850 struct RGB_t {
2851 Int_t fRGB[3];
2852 };
2853
2854 RGB_t gColorTriplets[] = {{{255, 0, 0}},
2855 {{0, 255, 0}},
2856 {{0, 0, 255}},
2857 {{255, 255, 0}},
2858 {{255, 0, 255}},
2859 {{0, 255, 255}},
2860 {{255, 255, 255}}};
2861
2862 Bool_t operator < (const RGB_t &lhs, const RGB_t &rhs)
2863 {
2864 if (lhs.fRGB[0] < rhs.fRGB[0])
2865 return kTRUE;
2866 else if (lhs.fRGB[0] > rhs.fRGB[0])
2867 return kFALSE;
2868 else if (lhs.fRGB[1] < rhs.fRGB[1])
2869 return kTRUE;
2870 else if (lhs.fRGB[1] > rhs.fRGB[1])
2871 return kFALSE;
2872 else if (lhs.fRGB[2] < rhs.fRGB[2])
2873 return kTRUE;
2874
2875 return kFALSE;
2876 }
2877
2878 typedef std::map<Int_t, RGB_t> ColorLookupTable_t;
2879 typedef ColorLookupTable_t::const_iterator CLTCI_t;
2880
2881 ColorLookupTable_t gObjectIDToColor;
2882
2883 typedef std::map<RGB_t, Int_t> ObjectLookupTable_t;
2884 typedef ObjectLookupTable_t::const_iterator OLTCI_t;
2885
2886 ObjectLookupTable_t gColorToObjectID;
2887}
2888////////////////////////////////////////////////////////////////////////////////
2889///Object id encoded as rgb triplet.
2890
2891void ObjectIDToColor(Int_t objectID, Bool_t highColor)
2892{
2893 if (!highColor)
2894 glColor3ub(objectID & 0xff, (objectID & 0xff00) >> 8, (objectID & 0xff0000) >> 16);
2895 else {
2896 if (!gObjectIDToColor.size()) {
2897 //Initialize lookup tables.
2898 for (Int_t i = 0, id = 1; i < Int_t(sizeof gColorTriplets / sizeof(RGB_t)); ++i, ++id)
2899 gObjectIDToColor[id] = gColorTriplets[i];
2900 for (Int_t i = 0, id = 1; i < Int_t(sizeof gColorTriplets / sizeof(RGB_t)); ++i, ++id)
2901 gColorToObjectID[gColorTriplets[i]] = id;
2902 }
2903
2904 CLTCI_t it = gObjectIDToColor.find(objectID);
2905
2906 if (it != gObjectIDToColor.end())
2907 glColor3ub(it->second.fRGB[0], it->second.fRGB[1], it->second.fRGB[2]);
2908 else {
2909 Error("ObjectIDToColor", "No color for such object ID: %d", objectID);
2910 glColor3ub(0, 0, 0);
2911 }
2912 }
2913}
2914
2915////////////////////////////////////////////////////////////////////////////////
2916
2917Int_t ColorToObjectID(const UChar_t *pixel, Bool_t highColor)
2918{
2919 if (!highColor)
2920 return pixel[0] | (pixel[1] << 8) | (pixel[2] << 16);
2921 else {
2922 if (!gObjectIDToColor.size())
2923 return 0;
2924
2925 RGB_t triplet = {{pixel[0], pixel[1], pixel[2]}};
2926 OLTCI_t it = gColorToObjectID.find(triplet);
2927
2928 if (it != gColorToObjectID.end())
2929 return it->second;
2930 else
2931 return 0;
2932 }
2933}
2934
2935
2936////////////////////////////////////////////////////////////////////////////////
2937///Draw quad outline.
2938
2940 const TGLVertex3 &v3, const TGLVertex3 &v4)
2941{
2942 glBegin(GL_LINE_LOOP);
2943 glVertex3dv(v1.CArr());
2944 glVertex3dv(v2.CArr());
2945 glVertex3dv(v3.CArr());
2946 glVertex3dv(v4.CArr());
2947 glEnd();
2948}
2949
2950////////////////////////////////////////////////////////////////////////////////
2951///Draw quad face.
2952
2954 const TGLVertex3 &v3, const TGLVector3 &normal)
2955{
2956 glBegin(GL_POLYGON);
2957 glNormal3dv(normal.CArr());
2958 glVertex3dv(v0.CArr());
2959 glVertex3dv(v1.CArr());
2960 glVertex3dv(v2.CArr());
2961 glVertex3dv(v3.CArr());
2962 glEnd();
2963}
2964
2965////////////////////////////////////////////////////////////////////////////////
2966///Draw quad face.
2967
2968void DrawQuadFilled(const Double_t *v0, const Double_t *v1, const Double_t *v2, const Double_t *v3,
2969 const Double_t *normal)
2970{
2971 glBegin(GL_QUADS);
2972 glNormal3dv(normal);
2973 glVertex3dv(v0);
2974 glVertex3dv(v1);
2975 glVertex3dv(v2);
2976 glVertex3dv(v3);
2977 glEnd();
2978}
2979
2980////////////////////////////////////////////////////////////////////////////////
2981///Draws triangle face, each vertex has its own averaged normal
2982
2984 const TGLVector3 &norm1, const TGLVector3 &norm2, const TGLVector3 &norm3)
2985{
2986 glBegin(GL_POLYGON);
2987 glNormal3dv(norm1.CArr());
2988 glVertex3dv(v1.CArr());
2989 glNormal3dv(norm2.CArr());
2990 glVertex3dv(v2.CArr());
2991 glNormal3dv(norm3.CArr());
2992 glVertex3dv(v3.CArr());
2993 glEnd();
2994}
2995
2996const Int_t gBoxFrontQuads[][4] = {{0, 1, 2, 3}, {4, 0, 3, 5}, {4, 5, 6, 7}, {7, 6, 2, 1}};
2997const Double_t gBoxFrontNormals[][3] = {{-1., 0., 0.}, {0., -1., 0.}, {1., 0., 0.}, {0., 1., 0.}};
2998const Int_t gBoxFrontPlanes[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 0}};
2999
3000const Int_t gBoxBackQuads[][4] = {{7, 1, 2, 6}, {4, 7, 6, 5}, {0, 4, 5, 3}, {0, 3, 2, 1}};
3001const Double_t gBoxBackNormals[][3] = {{0., -1., 0.}, {-1., 0., 0.}, {0., 1., 0.}, {1., 0., 0.}};
3002const Int_t gBoxBackPlanes[][2] = {{0, 1}, {3, 0}, {2, 3}, {1, 2}};
3003
3004////////////////////////////////////////////////////////////////////////////////
3005///Draws lego's bar as a 3d box
3006
3007void DrawBoxFront(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax,
3008 Double_t zMin, Double_t zMax, Int_t fp)
3009{
3010 if (zMax < zMin)
3011 std::swap(zMax, zMin);
3012
3013 //Bottom is always drawn.
3014 glBegin(GL_POLYGON);
3015 glNormal3d(0., 0., -1.);
3016 glVertex3d(xMax, yMin, zMin);
3017 glVertex3d(xMin, yMin, zMin);
3018 glVertex3d(xMin, yMax, zMin);
3019 glVertex3d(xMax, yMax, zMin);
3020 glEnd();
3021 //Draw two visible front planes.
3022 const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
3023 {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
3024 const Int_t *verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
3025
3026 glBegin(GL_POLYGON);
3027 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][0]]);
3028 glVertex3dv(box[verts[0]]);
3029 glVertex3dv(box[verts[1]]);
3030 glVertex3dv(box[verts[2]]);
3031 glVertex3dv(box[verts[3]]);
3032 glEnd();
3033
3034 verts = gBoxFrontQuads[gBoxFrontPlanes[fp][1]];
3035
3036 glBegin(GL_POLYGON);
3037 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][1]]);
3038 glVertex3dv(box[verts[0]]);
3039 glVertex3dv(box[verts[1]]);
3040 glVertex3dv(box[verts[2]]);
3041 glVertex3dv(box[verts[3]]);
3042 glEnd();
3043
3044 //Top is always drawn.
3045 glBegin(GL_POLYGON);
3046 glNormal3d(0., 0., 1.);
3047 glVertex3d(xMax, yMin, zMax);
3048 glVertex3d(xMax, yMax, zMax);
3049 glVertex3d(xMin, yMax, zMax);
3050 glVertex3d(xMin, yMin, zMax);
3051 glEnd();
3052}
3053
3054////////////////////////////////////////////////////////////////////////////////
3055///Draws lego's bar as a 3d box
3056
3058 Double_t zMin, Double_t zMax, Int_t fp)
3059{
3060 if (zMax < zMin)
3061 std::swap(zMax, zMin);
3062
3063 //The order is: 1) two back planes, 2) bottom plane, 3) two front planes,
3064 //4) top.
3065
3066 //Bottom is always drawn.
3067 glBegin(GL_POLYGON);
3068 glNormal3d(0., 0., -1.);
3069 glVertex3d(xMax, yMin, zMin);
3070 glVertex3d(xMin, yMin, zMin);
3071 glVertex3d(xMin, yMax, zMin);
3072 glVertex3d(xMax, yMax, zMin);
3073 glEnd();
3074
3075 const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
3076 {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
3077
3078 //Draw two back planes.
3079 const Int_t *verts = gBoxBackQuads[gBoxBackPlanes[fp][0]];
3080
3081 glBegin(GL_POLYGON);
3082 glNormal3dv(gBoxBackNormals[gBoxBackPlanes[fp][0]]);
3083 glVertex3dv(box[verts[0]]);
3084 glVertex3dv(box[verts[1]]);
3085 glVertex3dv(box[verts[2]]);
3086 glVertex3dv(box[verts[3]]);
3087 glEnd();
3088
3089 verts = gBoxBackQuads[gBoxBackPlanes[fp][1]];
3090
3091 glBegin(GL_POLYGON);
3092 glNormal3dv(gBoxBackNormals[gBoxBackPlanes[fp][1]]);
3093 glVertex3dv(box[verts[0]]);
3094 glVertex3dv(box[verts[1]]);
3095 glVertex3dv(box[verts[2]]);
3096 glVertex3dv(box[verts[3]]);
3097 glEnd();
3098
3099 //Draw two visible front planes.
3100 verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
3101
3102 glBegin(GL_POLYGON);
3103 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][0]]);
3104 glVertex3dv(box[verts[0]]);
3105 glVertex3dv(box[verts[1]]);
3106 glVertex3dv(box[verts[2]]);
3107 glVertex3dv(box[verts[3]]);
3108 glEnd();
3109
3110 verts = gBoxFrontQuads[gBoxFrontPlanes[fp][1]];
3111
3112 glBegin(GL_POLYGON);
3113 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][1]]);
3114 glVertex3dv(box[verts[0]]);
3115 glVertex3dv(box[verts[1]]);
3116 glVertex3dv(box[verts[2]]);
3117 glVertex3dv(box[verts[3]]);
3118 glEnd();
3119
3120 //Top is always drawn.
3121 glBegin(GL_POLYGON);
3122 glNormal3d(0., 0., 1.);
3123 glVertex3d(xMax, yMin, zMax);
3124 glVertex3d(xMax, yMax, zMax);
3125 glVertex3d(xMin, yMax, zMax);
3126 glVertex3d(xMin, yMin, zMax);
3127 glEnd();
3128}
3129
3130////////////////////////////////////////////////////////////////////////////////
3131///Draws lego's bar as a 3d box
3132///LULULULU
3133
3135 Double_t yMax, Double_t zMin, Double_t zMax,
3136 Double_t texMin, Double_t texMax, Int_t fp)
3137{
3138 if (zMax < zMin) {
3139 std::swap(zMax, zMin);
3140 std::swap(texMax, texMin);
3141 }
3142
3143 //Top and bottom are always drawn.
3144 glBegin(GL_POLYGON);
3145 glNormal3d(0., 0., 1.);
3146 glTexCoord1d(texMax);
3147 glVertex3d(xMax, yMin, zMax);
3148 glVertex3d(xMax, yMax, zMax);
3149 glVertex3d(xMin, yMax, zMax);
3150 glVertex3d(xMin, yMin, zMax);
3151 glEnd();
3152
3153 glBegin(GL_POLYGON);
3154 glTexCoord1d(texMin);
3155 glNormal3d(0., 0., -1.);
3156 glVertex3d(xMax, yMin, zMin);
3157 glVertex3d(xMin, yMin, zMin);
3158 glVertex3d(xMin, yMax, zMin);
3159 glVertex3d(xMax, yMax, zMin);
3160 glEnd();
3161 //Draw two visible front planes.
3162 const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
3163 {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
3164
3165 const Double_t tex[] = {texMax, texMax, texMin, texMin, texMax, texMin, texMin, texMax};
3166 const Int_t *verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
3167
3168 glBegin(GL_POLYGON);
3169 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][0]]);
3170 glTexCoord1d(tex[verts[0]]);
3171 glVertex3dv(box[verts[0]]);
3172 glTexCoord1d(tex[verts[1]]);
3173 glVertex3dv(box[verts[1]]);
3174 glTexCoord1d(tex[verts[2]]);
3175 glVertex3dv(box[verts[2]]);
3176 glTexCoord1d(tex[verts[3]]);
3177 glVertex3dv(box[verts[3]]);
3178 glEnd();
3179
3180 verts = gBoxFrontQuads[gBoxFrontPlanes[fp][1]];
3181
3182 glBegin(GL_POLYGON);
3183 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][1]]);
3184 glTexCoord1d(tex[verts[0]]);
3185 glVertex3dv(box[verts[0]]);
3186 glTexCoord1d(tex[verts[1]]);
3187 glVertex3dv(box[verts[1]]);
3188 glTexCoord1d(tex[verts[2]]);
3189 glVertex3dv(box[verts[2]]);
3190 glTexCoord1d(tex[verts[3]]);
3191 glVertex3dv(box[verts[3]]);
3192 glEnd();
3193}
3194
3195////////////////////////////////////////////////////////////////////////////////
3196
3198 const Double_t *rgba1, const Double_t *rgba2)
3199{
3200 assert(rgba1 != 0 && "DrawBoxWithGradientFill, parameter 'rgba1' is null");
3201 assert(rgba2 != 0 && "DrawBoxWithGradientFill, parameter 'rgba2' is null");
3202
3203 glBegin(GL_POLYGON);
3204 glColor4dv(rgba1);
3205 glVertex2d(x1, y1);
3206 glVertex2d(x2, y1);
3207 glColor4dv(rgba2);
3208 glVertex2d(x2, y2);
3209 glVertex2d(x1, y2);
3210 glEnd();
3211}
3212
3213////////////////////////////////////////////////////////////////////////////////
3214///TODO: is it possible to use GLdouble to avoid problems with Double_t/GLdouble if they
3215///are not the same type?
3216
3217void DrawQuadStripWithRadialGradientFill(unsigned nPoints, const Double_t *inner, const Double_t *innerRGBA,
3218 const Double_t *outer, const Double_t *outerRGBA)
3219{
3220 assert(nPoints != 0 &&
3221 "DrawQuadStripWithRadialGradientFill, invalid number of points");
3222 assert(inner != 0 &&
3223 "DrawQuadStripWithRadialGradientFill, parameter 'inner' is null");
3224 assert(innerRGBA != 0 &&
3225 "DrawQuadStripWithRadialGradientFill, parameter 'innerRGBA' is null");
3226 assert(outer != 0 &&
3227 "DrawQuadStripWithRadialGradientFill, parameter 'outer' is null");
3228 assert(outerRGBA != 0 &&
3229 "DrawQuadStripWithRadialGradientFill, parameter 'outerRGBA' is null");
3230
3231 glBegin(GL_QUAD_STRIP);
3232 for (UInt_t j = 0; j < nPoints; ++j) {
3233 glColor4dv(innerRGBA);
3234 glVertex2dv(inner + j * 2);
3235 glColor4dv(outerRGBA);
3236 glVertex2dv(outer + j * 2);
3237 }
3238 glEnd();
3239}
3240
3241////////////////////////////////////////////////////////////////////////////////
3242///Cylinder for lego3.
3243
3244void DrawCylinder(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin,
3245 Double_t yMax, Double_t zMin, Double_t zMax)
3246{
3247 GLUquadric *quad = quadric->Get();
3248
3249 if (quad) {
3250 if (zMin > zMax)
3251 std::swap(zMin, zMax);
3252 const Double_t xCenter = xMin + (xMax - xMin) / 2;
3253 const Double_t yCenter = yMin + (yMax - yMin) / 2;
3254 const Double_t radius = TMath::Min((xMax - xMin) / 2, (yMax - yMin) / 2);
3255
3256 glPushMatrix();
3257 glTranslated(xCenter, yCenter, zMin);
3258 gluCylinder(quad, radius, radius, zMax - zMin, 40, 1);
3259 glPopMatrix();
3260 glPushMatrix();
3261 glTranslated(xCenter, yCenter, zMax);
3262 gluDisk(quad, 0., radius, 40, 1);
3263 glPopMatrix();
3264 glPushMatrix();
3265 glTranslated(xCenter, yCenter, zMin);
3266 glRotated(180., 0., 1., 0.);
3267 gluDisk(quad, 0., radius, 40, 1);
3268 glPopMatrix();
3269 }
3270}
3271
3272////////////////////////////////////////////////////////////////////////////////
3273///Cylinder for lego3.
3274
3275void DrawSphere(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin,
3276 Double_t yMax, Double_t zMin, Double_t zMax)
3277{
3278 GLUquadric *quad = quadric->Get();
3279
3280 if (quad) {
3281 const Double_t xCenter = xMin + (xMax - xMin) / 2;
3282 const Double_t yCenter = yMin + (yMax - yMin) / 2;
3283 const Double_t zCenter = zMin + (zMax - zMin) / 2;
3284
3285 const Double_t radius = TMath::Min((zMax - zMin) / 2,
3286 TMath::Min((xMax - xMin) / 2, (yMax - yMin) / 2));
3287
3288 glPushMatrix();
3289 glTranslated(xCenter, yCenter, zCenter);
3290 gluSphere(quad, radius, 10, 10);
3291 glPopMatrix();
3292 }
3293}
3294
3295
3296////////////////////////////////////////////////////////////////////////////////
3297
3298void DrawError(Double_t xMin, Double_t xMax, Double_t yMin,
3299 Double_t yMax, Double_t zMin, Double_t zMax)
3300{
3301 const Double_t xWid = xMax - xMin;
3302 const Double_t yWid = yMax - yMin;
3303
3304 glBegin(GL_LINES);
3305 glVertex3d(xMin + xWid / 2, yMin + yWid / 2, zMin);
3306 glVertex3d(xMin + xWid / 2, yMin + yWid / 2, zMax);
3307 glEnd();
3308
3309 glBegin(GL_LINES);
3310 glVertex3d(xMin + xWid / 2, yMin, zMin);
3311 glVertex3d(xMin + xWid / 2, yMax, zMin);
3312 glEnd();
3313
3314 glBegin(GL_LINES);
3315 glVertex3d(xMin, yMin + yWid / 2, zMin);
3316 glVertex3d(xMax, yMin + yWid / 2, zMin);
3317 glEnd();
3318}
3319
3321{
3322 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1]);
3323 if (n > 0.) {
3324 normal[0] = v[0] / n;
3325 normal[1] = v[1] / n;
3326 normal[2] = 0.;
3327 } else {
3328 normal[0] = v[0];
3329 normal[1] = v[1];
3330 normal[2] = 0.;
3331 }
3332}
3333
3335{
3336 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1]);
3337 if (n > 0.) {
3338 normal[0] = -v[0] / n;
3339 normal[1] = -v[1] / n;
3340 normal[2] = 0.;
3341 } else {
3342 normal[0] = -v[0];
3343 normal[1] = -v[1];
3344 normal[2] = 0.;
3345 }
3346}
3347
3348void DrawTrapezoid(const Double_t ver[][2], Double_t zMin, Double_t zMax, Bool_t color)
3349{
3350 //In polar coordinates, box became trapezoid.
3351 //Four faces need normal calculations.
3352 if (zMin > zMax)
3353 std::swap(zMin, zMax);
3354 //top
3355 glBegin(GL_POLYGON);
3356 glNormal3d(0., 0., 1.);
3357 glVertex3d(ver[0][0], ver[0][1], zMax);
3358 glVertex3d(ver[1][0], ver[1][1], zMax);
3359 glVertex3d(ver[2][0], ver[2][1], zMax);
3360 glVertex3d(ver[3][0], ver[3][1], zMax);
3361 glEnd();
3362 //bottom
3363 glBegin(GL_POLYGON);
3364 glNormal3d(0., 0., -1.);
3365 glVertex3d(ver[0][0], ver[0][1], zMin);
3366 glVertex3d(ver[3][0], ver[3][1], zMin);
3367 glVertex3d(ver[2][0], ver[2][1], zMin);
3368 glVertex3d(ver[1][0], ver[1][1], zMin);
3369 glEnd();
3370 //
3371
3372 Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
3373 {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
3374 {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
3375 {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
3376 Double_t normal[3] = {0.};
3377 glBegin(GL_POLYGON);
3378 CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glVertex3dv(trapezoid[1]);
3379 CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glVertex3dv(trapezoid[2]);
3380 CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glVertex3dv(trapezoid[6]);
3381 CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glVertex3dv(trapezoid[5]);
3382 glEnd();
3383
3384 glBegin(GL_POLYGON);
3385 CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glVertex3dv(trapezoid[0]);
3386 CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glVertex3dv(trapezoid[4]);
3387 CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glVertex3dv(trapezoid[7]);
3388 CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glVertex3dv(trapezoid[3]);
3389 glEnd();
3390
3391 glBegin(GL_POLYGON);
3392 if (color) {
3393 TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
3394 glNormal3dv(normal);
3395 }
3396 glVertex3dv(trapezoid[0]);
3397 glVertex3dv(trapezoid[1]);
3398 glVertex3dv(trapezoid[5]);
3399 glVertex3dv(trapezoid[4]);
3400 glEnd();
3401
3402 glBegin(GL_POLYGON);
3403 if (color) {
3404 TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
3405 glNormal3dv(normal);
3406 }
3407 glVertex3dv(trapezoid[3]);
3408 glVertex3dv(trapezoid[7]);
3409 glVertex3dv(trapezoid[6]);
3410 glVertex3dv(trapezoid[2]);
3411 glEnd();
3412}
3413
3414////////////////////////////////////////////////////////////////////////////////
3415///In polar coordinates, box became trapezoid.
3416///Four faces need normal calculations.
3417
3418void DrawTrapezoidTextured(const Double_t ver[][2], Double_t zMin, Double_t zMax,
3419 Double_t texMin, Double_t texMax)
3420{
3421 if (zMin > zMax) {
3422 std::swap(zMin, zMax);
3423 std::swap(texMin, texMax);
3424 }
3425
3426 //top
3427 glBegin(GL_POLYGON);
3428 glNormal3d(0., 0., 1.);
3429 glTexCoord1d(texMax);
3430 glVertex3d(ver[0][0], ver[0][1], zMax);
3431 glVertex3d(ver[1][0], ver[1][1], zMax);
3432 glVertex3d(ver[2][0], ver[2][1], zMax);
3433 glVertex3d(ver[3][0], ver[3][1], zMax);
3434 glEnd();
3435 //bottom
3436 glBegin(GL_POLYGON);
3437 glNormal3d(0., 0., -1.);
3438 glTexCoord1d(texMin);
3439 glVertex3d(ver[0][0], ver[0][1], zMin);
3440 glVertex3d(ver[3][0], ver[3][1], zMin);
3441 glVertex3d(ver[2][0], ver[2][1], zMin);
3442 glVertex3d(ver[1][0], ver[1][1], zMin);
3443 glEnd();
3444 //
3445
3446 Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
3447 {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
3448 {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
3449 {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
3450 Double_t normal[3] = {0.};
3451 glBegin(GL_POLYGON);
3452 CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[1]);
3453 CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[2]);
3454 CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[6]);
3455 CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[5]);
3456 glEnd();
3457
3458 glBegin(GL_POLYGON);
3459 CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[0]);
3460 CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[4]);
3461 CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[7]);
3462 CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[3]);
3463 glEnd();
3464
3465 glBegin(GL_POLYGON);
3466 TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
3467 glNormal3dv(normal);
3468 glTexCoord1d(texMin);
3469 glVertex3dv(trapezoid[0]);
3470 glTexCoord1d(texMin);
3471 glVertex3dv(trapezoid[1]);
3472 glTexCoord1d(texMax);
3473 glVertex3dv(trapezoid[5]);
3474 glTexCoord1d(texMax);
3475 glVertex3dv(trapezoid[4]);
3476 glEnd();
3477
3478 glBegin(GL_POLYGON);
3479 TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
3480 glNormal3dv(normal);
3481 glTexCoord1d(texMin);
3482 glVertex3dv(trapezoid[3]);
3483 glTexCoord1d(texMax);
3484 glVertex3dv(trapezoid[7]);
3485 glTexCoord1d(texMax);
3486 glVertex3dv(trapezoid[6]);
3487 glTexCoord1d(texMin);
3488 glVertex3dv(trapezoid[2]);
3489 glEnd();
3490}
3491
3492////////////////////////////////////////////////////////////////////////////////
3493///In polar coordinates, box became trapezoid.
3494
3495void DrawTrapezoidTextured2(const Double_t ver[][2], Double_t zMin, Double_t zMax,
3496 Double_t texMin, Double_t texMax)
3497{
3498 if (zMin > zMax)
3499 std::swap(zMin, zMax);
3500
3501 const Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
3502 {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
3503 {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
3504 {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
3505 const Double_t tex[] = {texMin, texMax, texMax, texMin, texMin, texMax, texMax, texMin};
3506 //top
3507 glBegin(GL_POLYGON);
3508 glNormal3d(0., 0., 1.);
3509 glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
3510 glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
3511 glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
3512 glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
3513 glEnd();
3514 //bottom
3515 glBegin(GL_POLYGON);
3516 glNormal3d(0., 0., -1.);
3517 glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
3518 glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
3519 glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
3520 glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
3521 glEnd();
3522 //
3523 glBegin(GL_POLYGON);
3524 Double_t normal[3] = {};
3525 CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
3526 CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
3527 CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
3528 CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
3529 glEnd();
3530
3531 glBegin(GL_POLYGON);
3532 CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
3533 CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
3534 CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
3535 CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
3536 glEnd();
3537
3538 glBegin(GL_POLYGON);
3539 TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
3540 glNormal3dv(normal);
3541 glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
3542 glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
3543 glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
3544 glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
3545 glEnd();
3546
3547 glBegin(GL_POLYGON);
3548 TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
3549 glNormal3dv(normal);
3550 glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
3551 glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
3552 glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
3553 glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
3554 glEnd();
3555}
3556
3557////////////////////////////////////////////////////////////////////////////////
3558
3559void SphericalNormal(const Double_t *v, Double_t *normal)
3560{
3561 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
3562 if (n > 0.) {
3563 normal[0] = v[0] / n;
3564 normal[1] = v[1] / n;
3565 normal[2] = v[2] / n;
3566 } else {
3567 normal[0] = v[0];
3568 normal[1] = v[1];
3569 normal[2] = v[2];
3570 }
3571}
3572
3573////////////////////////////////////////////////////////////////////////////////
3574
3576{
3577 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
3578 if (n > 0.) {
3579 normal[0] = -v[0] / n;
3580 normal[1] = -v[1] / n;
3581 normal[2] = -v[2] / n;
3582 } else {
3583 normal[0] = -v[0];
3584 normal[1] = -v[1];
3585 normal[2] = -v[2];
3586 }
3587}
3588
3589////////////////////////////////////////////////////////////////////////////////
3590
3591void DrawTrapezoid(const Double_t ver[][3])
3592{
3593 Double_t normal[3] = {0.};
3594
3595 glBegin(GL_POLYGON);
3596 TMath::Normal2Plane(ver[1], ver[2], ver[3], normal);
3597 glNormal3dv(normal);
3598 glVertex3dv(ver[0]);
3599 glVertex3dv(ver[1]);
3600 glVertex3dv(ver[2]);
3601 glVertex3dv(ver[3]);
3602 glEnd();
3603 //bottom
3604 glBegin(GL_POLYGON);
3605 TMath::Normal2Plane(ver[4], ver[7], ver[6], normal);
3606 glNormal3dv(normal);
3607 glVertex3dv(ver[4]);
3608 glVertex3dv(ver[7]);
3609 glVertex3dv(ver[6]);
3610 glVertex3dv(ver[5]);
3611 glEnd();
3612 //
3613
3614 glBegin(GL_POLYGON);
3615 TMath::Normal2Plane(ver[0], ver[3], ver[7], normal);
3616 glNormal3dv(normal);
3617 glVertex3dv(ver[0]);
3618 glVertex3dv(ver[3]);
3619 glVertex3dv(ver[7]);
3620 glVertex3dv(ver[4]);
3621 glEnd();
3622
3623 glBegin(GL_POLYGON);
3624 SphericalNormal(ver[3], normal), glNormal3dv(normal), glVertex3dv(ver[3]);
3625 SphericalNormal(ver[2], normal), glNormal3dv(normal), glVertex3dv(ver[2]);
3626 SphericalNormal(ver[6], normal), glNormal3dv(normal), glVertex3dv(ver[6]);
3627 SphericalNormal(ver[7], normal), glNormal3dv(normal), glVertex3dv(ver[7]);
3628 glEnd();
3629
3630 glBegin(GL_POLYGON);
3631 TMath::Normal2Plane(ver[5], ver[6], ver[2], normal);
3632 glNormal3dv(normal);
3633 glVertex3dv(ver[5]);
3634 glVertex3dv(ver[6]);
3635 glVertex3dv(ver[2]);
3636 glVertex3dv(ver[1]);
3637 glEnd();
3638
3639 glBegin(GL_POLYGON);
3640 SphericalNormalInv(ver[0], normal), glNormal3dv(normal), glVertex3dv(ver[0]);
3641 SphericalNormalInv(ver[4], normal), glNormal3dv(normal), glVertex3dv(ver[4]);
3642 SphericalNormalInv(ver[5], normal), glNormal3dv(normal), glVertex3dv(ver[5]);
3643 SphericalNormalInv(ver[1], normal), glNormal3dv(normal), glVertex3dv(ver[1]);
3644 glEnd();
3645}
3646
3647////////////////////////////////////////////////////////////////////////////////
3648
3649void DrawTrapezoidTextured(const Double_t ver[][3], Double_t texMin, Double_t texMax)
3650{
3651 Double_t normal[3] = {};
3652 if (texMin > texMax)
3653 std::swap(texMin, texMax);
3654
3655 const Double_t tex[] = {texMin, texMin, texMax, texMax, texMin, texMin, texMax, texMax};
3656 glBegin(GL_POLYGON);
3657 TMath::Normal2Plane(ver[0], ver[1], ver[2], normal);
3658 glNormal3dv(normal);
3659 glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
3660 glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
3661 glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
3662 glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
3663 glEnd();
3664 glBegin(GL_POLYGON);
3665 TMath::Normal2Plane(ver[4], ver[7], ver[6], normal);
3666 glNormal3dv(normal);
3667 glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
3668 glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
3669 glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
3670 glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
3671 glEnd();
3672 glBegin(GL_POLYGON);
3673 TMath::Normal2Plane(ver[0], ver[3], ver[7], normal);
3674 glNormal3dv(normal);
3675 glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
3676 glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
3677 glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
3678 glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
3679 glEnd();
3680 glBegin(GL_POLYGON);
3681 SphericalNormal(ver[3], normal), glNormal3dv(normal), glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
3682 SphericalNormal(ver[2], normal), glNormal3dv(normal), glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
3683 SphericalNormal(ver[6], normal), glNormal3dv(normal), glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
3684 SphericalNormal(ver[7], normal), glNormal3dv(normal), glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
3685 glEnd();
3686 glBegin(GL_POLYGON);
3687 TMath::Normal2Plane(ver[5], ver[6], ver[2], normal);
3688 glNormal3dv(normal);
3689 glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
3690 glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
3691 glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
3692 glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
3693 glEnd();
3694 glBegin(GL_POLYGON);
3695 SphericalNormalInv(ver[0], normal), glNormal3dv(normal), glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
3696 SphericalNormalInv(ver[4], normal), glNormal3dv(normal), glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
3697 SphericalNormalInv(ver[5], normal), glNormal3dv(normal), glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
3698 SphericalNormalInv(ver[1], normal), glNormal3dv(normal), glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
3699 glEnd();
3700}
3701
3702
3703void Draw2DAxis(TAxis *axis, Double_t xMin, Double_t yMin, Double_t xMax, Double_t yMax,
3704 Double_t min, Double_t max, Bool_t log, Bool_t z = kFALSE)
3705{
3706 //Axes are drawn with help of TGaxis class
3707 std::string option;
3708 option.reserve(20);
3709
3710 if (xMin > xMax || z) option += "SDH=+";
3711 else option += "SDH=-";
3712
3713 if (log) option += 'G';
3714
3715 Int_t nDiv = axis->GetNdivisions();
3716
3717 if (nDiv < 0) {
3718 option += 'N';
3719 nDiv = -nDiv;
3720 }
3721
3722 TGaxis axisPainter;
3723 axisPainter.SetLineWidth(1);
3724
3725 static const Double_t zero = 0.001;
3726
3727 if (TMath::Abs(xMax - xMin) >= zero || TMath::Abs(yMax - yMin) >= zero) {
3728 axisPainter.ImportAxisAttributes(axis);
3729 axisPainter.SetLabelOffset(axis->GetLabelOffset() + axis->GetTickLength());
3730
3731 if (log) {
3732 min = TMath::Power(10, min);
3733 max = TMath::Power(10, max);
3734 }
3735 //Option time display is required ?
3736 if (axis->GetTimeDisplay()) {
3737 option += 't';
3738
3739 if (!strlen(axis->GetTimeFormatOnly()))
3740 axisPainter.SetTimeFormat(axis->ChooseTimeFormat(max - min));
3741 else
3742 axisPainter.SetTimeFormat(axis->GetTimeFormat());
3743 }
3744
3745 axisPainter.SetOption(option.c_str());
3746 axisPainter.PaintAxis(xMin, yMin, xMax, yMax, min, max, nDiv, option.c_str());
3747 }
3748}
3749
3750const Int_t gFramePoints[][2] = {{3, 1}, {0, 2}, {1, 3}, {2, 0}};
3751//Each point has two "neighbouring axes" (left and right). Axes types are 1 (ordinata) and 0 (abscissa)
3752const Int_t gAxisType[][2] = {{1, 0}, {0, 1}, {1, 0}, {0, 1}};
3753
3754////////////////////////////////////////////////////////////////////////////////
3755///Using front point, find, where to draw axes and which labels to use for them
3756///gVirtualX->SelectWindow(gGLManager->GetVirtualXInd(fGLDevice));
3757///gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
3758
3759void DrawAxes(Int_t fp, const Int_t *vp, const TGLVertex3 *box, const TGLPlotCoordinates *coord,
3760 TAxis *xAxis, TAxis *yAxis, TAxis *zAxis)
3761{
3762 const Int_t left = gFramePoints[fp][0];
3763 const Int_t right = gFramePoints[fp][1];
3764 const Double_t xLeft = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
3765 + box[left].X() - vp[0]));
3766 const Double_t yLeft = gPad->AbsPixeltoY(Int_t(vp[3] - box[left].Y()
3767 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3768 * gPad->GetWh() + vp[1]));
3769 const Double_t xMid = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
3770 + box[fp].X() - vp[0]));
3771 const Double_t yMid = gPad->AbsPixeltoY(Int_t(vp[3] - box[fp].Y()
3772 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3773 * gPad->GetWh() + vp[1]));
3774 const Double_t xRight = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC()
3775 * gPad->GetWw() + box[right].X() - vp[0]));
3776 const Double_t yRight = gPad->AbsPixeltoY(Int_t(vp[3] - box[right].Y()
3777 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3778 * gPad->GetWh() + vp[1]));
3779 const Double_t points[][2] = {{coord->GetXRange().first, coord->GetYRange().first },
3780 {coord->GetXRange().second, coord->GetYRange().first },
3781 {coord->GetXRange().second, coord->GetYRange().second},
3782 {coord->GetXRange().first, coord->GetYRange().second}};
3783 const Int_t leftType = gAxisType[fp][0];
3784 const Int_t rightType = gAxisType[fp][1];
3785 const Double_t leftLabel = points[left][leftType];
3786 const Double_t leftMidLabel = points[fp][leftType];
3787 const Double_t rightMidLabel = points[fp][rightType];
3788 const Double_t rightLabel = points[right][rightType];
3789
3790 if (xLeft - xMid || yLeft - yMid) {//To suppress error messages from TGaxis
3791 TAxis *axis = leftType ? yAxis : xAxis;
3792 if (leftLabel < leftMidLabel)
3793 Draw2DAxis(axis, xLeft, yLeft, xMid, yMid, leftLabel, leftMidLabel,
3794 leftType ? coord->GetYLog() : coord->GetXLog());
3795 else
3796 Draw2DAxis(axis, xMid, yMid, xLeft, yLeft, leftMidLabel, leftLabel,
3797 leftType ? coord->GetYLog() : coord->GetXLog());
3798 }
3799
3800 if (xRight - xMid || yRight - yMid) {//To suppress error messages from TGaxis
3801 TAxis *axis = rightType ? yAxis : xAxis;
3802
3803 if (rightMidLabel < rightLabel)
3804 Draw2DAxis(axis, xMid, yMid, xRight, yRight, rightMidLabel, rightLabel,
3805 rightType ? coord->GetYLog() : coord->GetXLog());
3806 else
3807 Draw2DAxis(axis, xRight, yRight, xMid, yMid, rightLabel, rightMidLabel,
3808 rightType ? coord->GetYLog() : coord->GetXLog());
3809 }
3810
3811 const Double_t xUp = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
3812 + box[left + 4].X() - vp[0]));
3813 const Double_t yUp = gPad->AbsPixeltoY(Int_t(vp[3] - box[left + 4].Y()
3814 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3815 * gPad->GetWh() + vp[1]));
3816 Draw2DAxis(zAxis, xLeft, yLeft, xUp, yUp, coord->GetZRange().first,
3817 coord->GetZRange().second, coord->GetZLog(), kTRUE);
3818}
3819
3820void SetZLevels(TAxis *zAxis, Double_t zMin, Double_t zMax,
3821 Double_t zScale, std::vector<Double_t> &zLevels)
3822{
3823 Int_t nDiv = zAxis->GetNdivisions() % 100;
3824 Int_t nBins = 0;
3825 Double_t binLow = 0., binHigh = 0., binWidth = 0.;
3826 THLimitsFinder::Optimize(zMin, zMax, nDiv, binLow, binHigh, nBins, binWidth, " ");
3827 zLevels.resize(nBins + 1);
3828
3829 for (Int_t i = 0; i < nBins + 1; ++i)
3830 zLevels[i] = (binLow + i * binWidth) * zScale;
3831}
3832
3833////////////////////////////////////////////////////////////////////////////////
3834///Draw textured triangle
3835
3837 Double_t t1, Double_t t2, Double_t t3, const TGLVector3 &norm1,
3838 const TGLVector3 &norm2, const TGLVector3 &norm3)
3839{
3840 glBegin(GL_POLYGON);
3841 glNormal3dv(norm1.CArr());
3842 glTexCoord1d(t1);
3843 glVertex3dv(v1.CArr());
3844 glNormal3dv(norm2.CArr());
3845 glTexCoord1d(t2);
3846 glVertex3dv(v2.CArr());
3847 glNormal3dv(norm3.CArr());
3848 glTexCoord1d(t3);
3849 glVertex3dv(v3.CArr());
3850 glEnd();
3851}
3852
3853////////////////////////////////////////////////////////////////////////////////
3854///Draw textured triangle on a plane
3855
3858 const TGLVector3 &normal)
3859{
3860 glBegin(GL_POLYGON);
3861 glNormal3dv(normal.CArr());
3862 glTexCoord1d(t1);
3863 glVertex3d(v1.X(), v1.Y(), z);
3864 glTexCoord1d(t2);
3865 glVertex3d(v2.X(), v2.Y(), z);
3866 glTexCoord1d(t3);
3867 glVertex3d(v3.X(), v3.Y(), z);
3868 glEnd();
3869}
3870
3871////////////////////////////////////////////////////////////////////////////////
3872///This function creates color for parametric surface's vertex,
3873///using its 'u' value.
3874///I've found it in one of Apple's Carbon tutorials , and it's based
3875///on Paul Bourke work. Very nice colors!!! :)
3876
3878{
3879 Float_t dv,vmid;
3880 //Float_t c[] = {1.f, 1.f, 1.f};
3881 Float_t c1[3] = {}, c2[3] = {}, c3[3] = {};
3882 Float_t ratio ;
3883 rgba[3] = 1.f;
3884
3885 if (v < vmin)
3886 v = vmin;
3887 if (v > vmax)
3888 v = vmax;
3889 dv = vmax - vmin;
3890
3891 switch (type) {
3892 case 0:
3893 rgba[0] = 1.f;
3894 rgba[1] = 1.f;
3895 rgba[2] = 1.f;
3896 break;
3897 case 1:
3898 if (v < (vmin + 0.25 * dv)) {
3899 rgba[0] = 0;
3900 rgba[1] = 4 * (v - vmin) / dv;
3901 rgba[2] = 1;
3902 } else if (v < (vmin + 0.5 * dv)) {
3903 rgba[0] = 0;
3904 rgba[1] = 1;
3905 rgba[2] = 1 + 4 * (vmin + 0.25 * dv - v) / dv;
3906 } else if (v < (vmin + 0.75 * dv)) {
3907 rgba[0] = 4 * (v - vmin - 0.5 * dv) / dv;
3908 rgba[1] = 1;
3909 rgba[2] = 0;
3910 } else {
3911 rgba[0] = 1;
3912 rgba[1] = 1 + 4 * (vmin + 0.75 * dv - v) / dv;
3913 rgba[2] = 0;
3914 }
3915 break;
3916 case 2:
3917 rgba[0] = (v - vmin) / dv;
3918 rgba[1] = 0;
3919 rgba[2] = (vmax - v) / dv;
3920 break;
3921 case 3:
3922 rgba[0] = (v - vmin) / dv;
3923 rgba[1] = rgba[0];
3924 rgba[2] = rgba[0];
3925 break;
3926 case 4:
3927 if (v < (vmin + dv / 6.0)) {
3928 rgba[0] = 1;
3929 rgba[1] = 6 * (v - vmin) / dv;
3930 rgba[2] = 0;
3931 } else if (v < (vmin + 2.0 * dv / 6.0)) {
3932 rgba[0] = 1 + 6 * (vmin + dv / 6.0 - v) / dv;
3933 rgba[1] = 1;
3934 rgba[2] = 0;
3935 } else if (v < (vmin + 3.0 * dv / 6.0)) {
3936 rgba[0] = 0;
3937 rgba[1] = 1;
3938 rgba[2] = 6 * (v - vmin - 2.0 * dv / 6.0) / dv;
3939 } else if (v < (vmin + 4.0 * dv / 6.0)) {
3940 rgba[0] = 0;
3941 rgba[1] = 1 + 6 * (vmin + 3.0 * dv / 6.0 - v) / dv;
3942 rgba[2] = 1;
3943 } else if (v < (vmin + 5.0 * dv / 6.0)) {
3944 rgba[0] = 6 * (v - vmin - 4.0 * dv / 6.0) / dv;
3945 rgba[1] = 0;
3946 rgba[2] = 1;
3947 } else {
3948 rgba[0] = 1;
3949 rgba[1] = 0;
3950 rgba[2] = 1 + 6 * (vmin + 5.0 * dv / 6.0 - v) / dv;
3951 }
3952 break;
3953 case 5:
3954 rgba[0] = (v - vmin) / (vmax - vmin);
3955 rgba[1] = 1;
3956 rgba[2] = 0;
3957 break;
3958 case 6:
3959 rgba[0] = (v - vmin) / (vmax - vmin);
3960 rgba[1] = (vmax - v) / (vmax - vmin);
3961 rgba[2] = rgba[0];
3962 break;
3963 case 7:
3964 if (v < (vmin + 0.25 * dv)) {
3965 rgba[0] = 0;
3966 rgba[1] = 4 * (v - vmin) / dv;
3967 rgba[2] = 1 - rgba[1];
3968 } else if (v < (vmin + 0.5 * dv)) {
3969 rgba[0] = 4 * (v - vmin - 0.25 * dv) / dv;
3970 rgba[1] = 1 - rgba[0];
3971 rgba[2] = 0;
3972 } else if (v < (vmin + 0.75 * dv)) {
3973 rgba[1] = 4 * (v - vmin - 0.5 * dv) / dv;
3974 rgba[0] = 1 - rgba[1];
3975 rgba[2] = 0;
3976 } else {
3977 rgba[0] = 0;
3978 rgba[2] = 4 * (v - vmin - 0.75 * dv) / dv;
3979 rgba[1] = 1 - rgba[2];
3980 }
3981 break;
3982 case 8:
3983 if (v < (vmin + 0.5 * dv)) {
3984 rgba[0] = 2 * (v - vmin) / dv;
3985 rgba[1] = rgba[0];
3986 rgba[2] = rgba[0];
3987 } else {
3988 rgba[0] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
3989 rgba[1] = rgba[0];
3990 rgba[2] = rgba[0];
3991 }
3992 break;
3993 case 9:
3994 if (v < (vmin + dv / 3)) {
3995 rgba[2] = 3 * (v - vmin) / dv;
3996 rgba[1] = 0;
3997 rgba[0] = 1 - rgba[2];
3998 } else if (v < (vmin + 2 * dv / 3)) {
3999 rgba[0] = 0;
4000 rgba[1] = 3 * (v - vmin - dv / 3) / dv;
4001 rgba[2] = 1;
4002 } else {
4003 rgba[0] = 3 * (v - vmin - 2 * dv / 3) / dv;
4004 rgba[1] = 1 - rgba[0];
4005 rgba[2] = 1;
4006 }
4007 break;
4008 case 10:
4009 if (v < (vmin + 0.2 * dv)) {
4010 rgba[0] = 0;
4011 rgba[1] = 5 * (v - vmin) / dv;
4012 rgba[2] = 1;
4013 } else if (v < (vmin + 0.4 * dv)) {
4014 rgba[0] = 0;
4015 rgba[1] = 1;
4016 rgba[2] = 1 + 5 * (vmin + 0.2 * dv - v) / dv;
4017 } else if (v < (vmin + 0.6 * dv)) {
4018 rgba[0] = 5 * (v - vmin - 0.4 * dv) / dv;
4019 rgba[1] = 1;
4020 rgba[2] = 0;
4021 } else if (v < (vmin + 0.8 * dv)) {
4022 rgba[0] = 1;
4023 rgba[1] = 1 - 5 * (v - vmin - 0.6 * dv) / dv;
4024 rgba[2] = 0;
4025 } else {
4026 rgba[0] = 1;
4027 rgba[1] = 5 * (v - vmin - 0.8 * dv) / dv;
4028 rgba[2] = 5 * (v - vmin - 0.8 * dv) / dv;
4029 }
4030 break;
4031 case 11:
4032 c1[0] = 200 / 255.0; c1[1] = 60 / 255.0; c1[2] = 0 / 255.0;
4033 c2[0] = 250 / 255.0; c2[1] = 160 / 255.0; c2[2] = 110 / 255.0;
4034 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / dv + c1[0];
4035 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / dv + c1[1];
4036 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / dv + c1[2];
4037 break;
4038 case 12:
4039 c1[0] = 55 / 255.0; c1[1] = 55 / 255.0; c1[2] = 45 / 255.0;
4040 c2[0] = 200 / 255.0; c2[1] = 60 / 255.0; c2[2] = 0 / 255.0;
4041 c3[0] = 250 / 255.0; c3[1] = 160 / 255.0; c3[2] = 110 / 255.0;
4042 ratio = 0.4;
4043 vmid = vmin + ratio * dv;
4044 if (v < vmid) {
4045 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
4046 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
4047 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
4048 } else {
4049 rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
4050 rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
4051 rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
4052 }
4053 break;
4054 case 13:
4055 c1[0] = 0 / 255.0; c1[1] = 255 / 255.0; c1[2] = 0 / 255.0;
4056 c2[0] = 255 / 255.0; c2[1] = 150 / 255.0; c2[2] = 0 / 255.0;
4057 c3[0] = 255 / 255.0; c3[1] = 250 / 255.0; c3[2] = 240 / 255.0;
4058 ratio = 0.3;
4059 vmid = vmin + ratio * dv;
4060 if (v < vmid) {
4061 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
4062 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
4063 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
4064 } else {
4065 rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
4066 rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
4067 rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
4068 }
4069 break;
4070 case 14:
4071 rgba[0] = 1;
4072 rgba[1] = 1 - (v - vmin) / dv;
4073 rgba[2] = 0;
4074 break;
4075 case 15:
4076 if (v < (vmin + 0.25 * dv)) {
4077 rgba[0] = 0;
4078 rgba[1] = 4 * (v - vmin) / dv;
4079 rgba[2] = 1;
4080 } else if (v < (vmin + 0.5 * dv)) {
4081 rgba[0] = 0;
4082 rgba[1] = 1;
4083 rgba[2] = 1 - 4 * (v - vmin - 0.25 * dv) / dv;
4084 } else if (v < (vmin + 0.75 * dv)) {
4085 rgba[0] = 4 * (v - vmin - 0.5 * dv) / dv;
4086 rgba[1] = 1;
4087 rgba[2] = 0;
4088 } else {
4089 rgba[0] = 1;
4090 rgba[1] = 1;
4091 rgba[2] = 4 * (v - vmin - 0.75 * dv) / dv;
4092 }
4093 break;
4094 case 16:
4095 if (v < (vmin + 0.5 * dv)) {
4096 rgba[0] = 0.0;
4097 rgba[1] = 2 * (v - vmin) / dv;
4098 rgba[2] = 1 - 2 * (v - vmin) / dv;
4099 } else {
4100 rgba[0] = 2 * (v - vmin - 0.5 * dv) / dv;
4101 rgba[1] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
4102 rgba[2] = 0.0;
4103 }
4104 break;
4105 case 17:
4106 if (v < (vmin + 0.5 * dv)) {
4107 rgba[0] = 1.0;
4108 rgba[1] = 1 - 2 * (v - vmin) / dv;
4109 rgba[2] = 2 * (v - vmin) / dv;
4110 } else {
4111 rgba[0] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
4112 rgba[1] = 2 * (v - vmin - 0.5 * dv) / dv;
4113 rgba[2] = 1.0;
4114 }
4115 break;
4116 case 18:
4117 rgba[0] = 0;
4118 rgba[1] = (v - vmin) / (vmax - vmin);
4119 rgba[2] = 1;
4120 break;
4121 case 19:
4122 rgba[0] = (v - vmin) / (vmax - vmin);
4123 rgba[1] = rgba[0];
4124 rgba[2] = 1;
4125 break;
4126 case 20:
4127 c1[0] = 0 / 255.0; c1[1] = 160 / 255.0; c1[2] = 0 / 255.0;
4128 c2[0] = 180 / 255.0; c2[1] = 220 / 255.0; c2[2] = 0 / 255.0;
4129 c3[0] = 250 / 255.0; c3[1] = 220 / 255.0; c3[2] = 170 / 255.0;
4130 ratio = 0.3;
4131 vmid = vmin + ratio * dv;
4132 if (v < vmid) {
4133 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
4134 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
4135 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
4136 } else {
4137 rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
4138 rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
4139 rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
4140 }
4141 break;
4142 }
4143}
4144
4145}
4146
4147////////////////////////////////////////////////////////////////////////////////
4148///Ctor.
4149
4151 : fContours(0),
4152 fPaletteSize(0),
4153 fTexture(0),
4154 fMaxPaletteSize(0)
4155{
4156}
4157
4158////////////////////////////////////////////////////////////////////////////////
4159///Try to find colors for palette.
4160
4162{
4163 if (!fMaxPaletteSize && check)
4164 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &fMaxPaletteSize);
4165
4166 if (!(zRange.second - zRange.first))
4167 return kFALSE;
4168
4169 if (!paletteSize) {
4170 Error("TGLLevelPaletter::GeneratePalette",
4171 "Invalid palette size, must be a positive number");
4172 return kFALSE;
4173 }
4174
4175 if (check && paletteSize > UInt_t(fMaxPaletteSize)) {
4176 Error("TGLLevelPalette::GeneratePalette",
4177 "Number of contours %d is too big for GL 1D texture, try to reduce it to %d",
4178 paletteSize, fMaxPaletteSize);
4179 return kFALSE;
4180 }
4181
4182 UInt_t nearestPow2 = 2;
4183 while (nearestPow2 < paletteSize)
4184 nearestPow2 <<= 1;
4185
4186 fTexels.resize(4 * nearestPow2);
4187 fPaletteSize = paletteSize;
4188
4189 //Generate texels.
4190 const Int_t nColors = gStyle->GetNumberOfColors();
4191
4192 //Map color index into index in real palette.
4193
4194 for (UInt_t i = 0; i < paletteSize; ++i) {
4195 Int_t paletteInd = Int_t(nColors / Double_t(paletteSize) * i);
4196 if (paletteInd > nColors - 1)
4197 paletteInd = nColors - 1;
4198 Int_t colorInd = gStyle->GetColorPalette(paletteInd);
4199
4200 if (const TColor *c = gROOT->GetColor(colorInd)) {
4201 Float_t rgb[3] = {};
4202 c->GetRGB(rgb[0], rgb[1], rgb[2]);
4203 fTexels[i * 4] = UChar_t(rgb[0] * 255);
4204 fTexels[i * 4 + 1] = UChar_t(rgb[1] * 255);
4205 fTexels[i * 4 + 2] = UChar_t(rgb[2] * 255);
4206 fTexels[i * 4 + 3] = 200;//alpha
4207 }
4208 }
4209
4210 fZRange = zRange;
4211
4212 return kTRUE;
4213}
4214
4215////////////////////////////////////////////////////////////////////////////////
4216///Clear :)
4217
4218void TGLLevelPalette::SetContours(const std::vector<Double_t> *cont)
4219{
4220 fContours = cont;
4221}
4222
4223////////////////////////////////////////////////////////////////////////////////
4224///Enable 1D texture
4225
4227{
4228 glEnable(GL_TEXTURE_1D);
4229
4230 glGenTextures(1, &fTexture);
4231
4232 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4233 glBindTexture(GL_TEXTURE_1D, fTexture);
4234 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
4235 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4236 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4237 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, fTexels.size() / 4, 0,
4238 GL_RGBA, GL_UNSIGNED_BYTE, &fTexels[0]);
4239 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GLint(mode));
4240}
4241
4242////////////////////////////////////////////////////////////////////////////////
4243///Disable 1D texture
4244
4246{
4247 glDeleteTextures(1, &fTexture);
4248 glDisable(GL_TEXTURE_1D);
4249}
4250
4251////////////////////////////////////////////////////////////////////////////////
4252///Get. Palette. Size.
4253
4255{
4256 return Int_t(fPaletteSize);
4257}
4258
4259////////////////////////////////////////////////////////////////////////////////
4260///Get tex coordinate
4261
4263{
4264 if (!fContours) {
4265 if (z - fZRange.first < 0)
4266 z = fZRange.first;
4267 else if (fZRange.second < z)
4268 z = fZRange.second;
4269
4270 return (z - fZRange.first) / (fZRange.second - fZRange.first) * fPaletteSize / (fTexels.size() / 4);
4271 }
4272 /*
4273 //This part is wrong. To be fixed.
4274 std::vector<Double_t>::size_type i = 0, e = fContours->size();
4275
4276 if (!e)
4277 return 0.;
4278
4279 for (; i < e - 1; ++i) {
4280 if (z >= (*fContours)[i] && z <= (*fContours)[i + 1])
4281 return i / Double_t(fTexels.size() / 4);
4282 }
4283 */
4284
4285 return 1.;
4286}
4287
4288////////////////////////////////////////////////////////////////////////////////
4289///Get color.
4290
4292{
4293 if (z - fZRange.first < 0)
4294 z = fZRange.first;
4295 else if (fZRange.second < z)
4296 z = fZRange.second;
4297
4298 UInt_t ind = UInt_t((z - fZRange.first) / (fZRange.second - fZRange.first) * fPaletteSize);
4299 if (ind >= fPaletteSize)
4300 ind = fPaletteSize - 1;
4301
4302 return &fTexels[ind * 4];
4303}
4304
4305////////////////////////////////////////////////////////////////////////////////
4306///Get color.
4307
4309{
4310 return &fTexels[ind * 4];
4311}
#define GLU_OUTSIDE
Definition: GL_glu.h:203
unsigned char GLubyte
Definition: GL_glu.h:273
void GLvoid
Definition: GL_glu.h:269
#define GL_QUADS
Definition: GL_glu.h:290
GLAPI GLUtesselator *GLAPIENTRY gluNewTess(void)
Definition: tess.c:102
#define GLU_VERTEX
Definition: GL_glu.h:210
#define GL_LINE_STRIP
Definition: GL_glu.h:286
#define GL_LINES
Definition: GL_glu.h:284
int GLint
Definition: GL_glu.h:272
unsigned int GLenum
Definition: GL_glu.h:266
#define GL_POINTS
Definition: GL_glu.h:283
#define GLU_BEGIN
Definition: GL_glu.h:208
#define GLU_INSIDE
Definition: GL_glu.h:204
GLAPI void GLAPIENTRY gluTessCallback(GLUtesselator *tess, GLenum which, _GLUfuncptr CallBackFunc)
Definition: tess.c:286
#define GL_POLYGON
Definition: GL_glu.h:292
#define GL_LINE_LOOP
Definition: GL_glu.h:285
#define GLU_END
Definition: GL_glu.h:212
GLAPI void GLAPIENTRY gluDeleteTess(GLUtesselator *tess)
Definition: tess.c:203
#define GL_QUAD_STRIP
Definition: GL_glu.h:291
ROOT::R::TRInterface & r
Definition: Object.C:4
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define c(i)
Definition: RSha256.hxx:101
#define g(i)
Definition: RSha256.hxx:105
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
static const double x2[5]
static const double x1[5]
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned short UShort_t
Definition: RtypesCore.h:40
int Int_t
Definition: RtypesCore.h:45
unsigned char UChar_t
Definition: RtypesCore.h:38
int Ssiz_t
Definition: RtypesCore.h:67
char Char_t
Definition: RtypesCore.h:33
unsigned int UInt_t
Definition: RtypesCore.h:46
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
double Double_t
Definition: RtypesCore.h:59
short Color_t
Definition: RtypesCore.h:92
float Float_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:364
Bool_t operator<(const TDatime &d1, const TDatime &d2)
Definition: TDatime.h:106
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
R__EXTERN TEnv * gEnv
Definition: TEnv.h:170
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition: TError.cxx:187
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition: TError.cxx:231
std::pair< Bool_t, TGLLine3 > Intersection(const TGLPlane &p1, const TGLPlane &p2)
Find 3D line interestion of this plane with 'other'.
Definition: TGLUtil.cxx:516
#define CALLBACK
Definition: TGLUtil.cxx:1432
Double_t Dot(const TGLVector3 &v1, const TGLVector3 &v2)
Definition: TGLUtil.h:317
TGLVector3 Cross(const TGLVector3 &v1, const TGLVector3 &v2)
Definition: TGLUtil.h:323
XFontStruct * id
Definition: TGX11.cxx:109
int type
Definition: TGX11.cxx:121
double cos(double)
double sqrt(double)
double sin(double)
double log(double)
#define gROOT
Definition: TROOT.h:404
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:412
#define gPad
Definition: TVirtualPad.h:287
#define gVirtualX
Definition: TVirtualX.h:338
point * points
Definition: X3DBuffer.c:22
virtual Int_t GetNdivisions() const
Definition: TAttAxis.h:36
virtual Float_t GetLabelOffset() const
Definition: TAttAxis.h:40
virtual Float_t GetTickLength() const
Definition: TAttAxis.h:45
Line Attributes class.
Definition: TAttLine.h:18
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
Marker Attributes class.
Definition: TAttMarker.h:19
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:32
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:31
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:33
Class to manage histogram axis.
Definition: TAxis.h:30
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:126
const char * ChooseTimeFormat(Double_t axislength=0)
Choose a reasonable time format from the coordinates in the active pad and the number of divisions in...
Definition: TAxis.cxx:126
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Definition: TAxis.cxx:571
virtual const char * GetTimeFormat() const
Definition: TAxis.h:127
The color creation and management class.
Definition: TColor.h:19
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition: TColor.cxx:1775
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
Concrete class describing an orientated (free) or axis aligned box of 8 vertices.
Double_t XMin() const
TGLVertex3 Center() const
Double_t ZMax() const
Double_t XMax() const
Double_t YMin() const
Double_t YMax() const
Double_t ZMin() const
Abstract base camera class - concrete classes for orthographic and perspective cameras derive from it...
Definition: TGLCamera.h:44
TGLVector3 WorldDeltaToViewport(const TGLVertex3 &worldRef, const TGLVector3 &worldDelta) const
Convert a 3D vector worldDelta (shift) about vertex worldRef to a viewport (screen) '3D' vector.
Definition: TGLCamera.cxx:426
TGLVector3 ViewportDeltaToWorld(const TGLVertex3 &worldRef, Double_t viewportXDelta, Double_t viewportYDelta, TGLMatrix *modviewMat=0) const
Apply a 2D viewport delta (shift) to the projection of worldRef onto viewport, returning the resultan...
Definition: TGLCamera.cxx:546
~TGLCapabilityEnabler()
Destructor - reset state if changed.
Definition: TGLUtil.cxx:2719
TGLCapabilityEnabler(const TGLCapabilityEnabler &)
TGLCapabilitySwitch(const TGLCapabilitySwitch &)
void SetState(Bool_t s)
Definition: TGLUtil.cxx:2696
~TGLCapabilitySwitch()
Destructor - reset state if changed.
Definition: TGLUtil.cxx:2688
Class encapsulating a set of colors used throughout standard rendering.
Definition: TGLUtil.h:836
TGLColor fSelection[5]
Definition: TGLUtil.h:842
void StdLightBackground()
Set defaults for light (white) background.
Definition: TGLUtil.cxx:1389
TGLColor fMarkup
Definition: TGLUtil.h:841
TGLColorSet & operator=(const TGLColorSet &s)
Assignment operator.
Definition: TGLUtil.cxx:1358
TGLColor fBackground
Definition: TGLUtil.h:838
TGLColor fOutline
Definition: TGLUtil.h:840
void StdDarkBackground()
Set defaults for dark (black) background.
Definition: TGLUtil.cxx:1372
TGLColorSet()
Constructor. Sets default for dark background.
Definition: TGLUtil.cxx:1337
TGLColor fForeground
Definition: TGLUtil.h:839
Class encapsulating color information in preferred GL format - an array of four unsigned bytes.
Definition: TGLUtil.h:785
void SetTransparency(Char_t transparency)
Set alpha from the transparency.
Definition: TGLUtil.cxx:1312
const UChar_t * CArr() const
Definition: TGLUtil.h:800
Char_t GetTransparency() const
Returns transparency value.
Definition: TGLUtil.cxx:1227
void SetColor(Int_t r, Int_t g, Int_t b, Int_t a=255)
Set color with Int_t values.
Definition: TGLUtil.cxx:1235
UChar_t GetBlue() const
Definition: TGLUtil.h:804
UChar_t fRGBA[4]
Definition: TGLUtil.h:787
TGLColor()
Default constructor. Color is initialized to black.
Definition: TGLUtil.cxx:1158
UChar_t GetRed() const
Definition: TGLUtil.h:802
TString AsString() const
Return string describing the color.
Definition: TGLUtil.cxx:1320
TGLColor & operator=(const TGLColor &c)
Assignment operator.
Definition: TGLUtil.cxx:1204
UChar_t GetGreen() const
Definition: TGLUtil.h:803
Color_t GetColorIndex() const
Returns color-index representing the color.
Definition: TGLUtil.cxx:1217
Short_t fIndex
Definition: TGLUtil.h:788
~TGLDisableGuard()
TGLDisableGuard destructor.
Definition: TGLUtil.cxx:2773
TGLDisableGuard(Int_t cap)
TGLDisableGuard constructor.
Definition: TGLUtil.cxx:2764
~TGLEnableGuard()
TGLEnableGuard destructor.
Definition: TGLUtil.cxx:2756
TGLEnableGuard(Int_t cap)
TGLEnableGuard constructor.
Definition: TGLUtil.cxx:2747
Bool_t fFlip
Definition: TGLUtil.h:1099
void(* fFoo)(Float_t)
Definition: TGLUtil.h:1100
TGLFloatHolder(const TGLFloatHolder &)
Float_t fState
Definition: TGLUtil.h:1098
const UChar_t * GetColour(Double_t z) const
Get color.
Definition: TGLUtil.cxx:4291
const std::vector< Double_t > * fContours
Definition: TGLUtil.h:1342
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition: TGLUtil.cxx:4254
void SetContours(const std::vector< Double_t > *contours)
Clear :)
Definition: TGLUtil.cxx:4218
UInt_t fPaletteSize
Definition: TGLUtil.h:1343
TGLLevelPalette()
Ctor.
Definition: TGLUtil.cxx:4150
std::vector< UChar_t > fTexels
Definition: TGLUtil.h:1341
void DisableTexture() const
Disable 1D texture.
Definition: TGLUtil.cxx:4245
Double_t GetTexCoord(Double_t z) const
Get tex coordinate.
Definition: TGLUtil.cxx:4262
Rgl::Range_t fZRange
Definition: TGLUtil.h:1346
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition: TGLUtil.cxx:4161
Int_t fMaxPaletteSize
Definition: TGLUtil.h:1345
UInt_t fTexture
Definition: TGLUtil.h:1344
void EnableTexture(Int_t mode) const
Enable 1D texture.
Definition: TGLUtil.cxx:4226
3D space, fixed length, line class, with direction / length 'vector', passing through point 'vertex'.
Definition: TGLUtil.h:387
TGLLine3(const TGLVertex3 &start, const TGLVertex3 &end)
Vector of line from fVertex.
Definition: TGLUtil.cxx:176
const TGLVertex3 End() const
Definition: TGLUtil.h:405
void Draw() const
Draw line in current basic GL color.
Definition: TGLUtil.cxx:211
TGLVector3 fVector
Start vertex of line.
Definition: TGLUtil.h:391
TGLVertex3 fVertex
Definition: TGLUtil.h:390
void Set(const TGLVertex3 &start, const TGLVertex3 &end)
Set 3D line running from 'start' to 'end'.
Definition: TGLUtil.cxx:192
16 component (4x4) transform matrix - column MAJOR as per GL.
Definition: TGLUtil.h:598
void MultLeft(const TGLMatrix &lhs)
Multiply with matrix lhs on left.
Definition: TGLUtil.cxx:718
TGLVector3 Multiply(const TGLVector3 &v, Double_t w=1) const
Multiply vector.
Definition: TGLUtil.cxx:1049
void Scale(const TGLVector3 &scale)
Set matrix axis scales to 'scale'.
Definition: TGLUtil.cxx:834
void Set(const TGLVertex3 &origin, const TGLVector3 &zAxis, const TGLVector3 &xAxis=0)
Set matrix which when applied puts local origin at 'origin' and the local Z axis in direction 'z'.
Definition: TGLUtil.cxx:736
void RotateLF(Int_t i1, Int_t i2, Double_t amount)
Rotate in local frame.
Definition: TGLUtil.cxx:897
Double_t Invert()
Invert the matrix, returns determinant.
Definition: TGLUtil.cxx:971
void MoveLF(Int_t ai, Double_t amount)
Translate in local frame.
Definition: TGLUtil.cxx:813
void SetIdentity()
Set matrix to identity.
Definition: TGLUtil.cxx:765
void Transpose3x3()
Transpose the top left 3x3 matrix component along major diagonal Supported as currently incompatibili...
Definition: TGLUtil.cxx:947
void RotatePF(Int_t i1, Int_t i2, Double_t amount)
Rotate in parent frame. Does optimised version of MultLeft.
Definition: TGLUtil.cxx:914
void Move3LF(Double_t x, Double_t y, Double_t z)
Translate in local frame along all base vectors simultaneously.
Definition: TGLUtil.cxx:822
const Double_t * CArr() const
Definition: TGLUtil.h:664
void Rotate(const TGLVertex3 &pivot, const TGLVector3 &axis, Double_t angle)
Update matrix so resulting transform has been rotated about 'pivot' (in parent frame),...
Definition: TGLUtil.cxx:870
virtual ~TGLMatrix()
Destroy matrix object.
Definition: TGLUtil.cxx:695
TGLVector3 GetTranslation() const
Return the translation component of matrix.
Definition: TGLUtil.cxx:794
Double_t fVals[16]
Definition: TGLUtil.h:601
void RotateIP(TGLVector3 &v) const
Rotate vector in-place. Translation is not applied.
Definition: TGLUtil.cxx:1087
Bool_t IsScalingForRender() const
Return true if matrix is to be considered a scaling matrix for rendering.
Definition: TGLUtil.cxx:1111
void TransformVertex(TGLVertex3 &vertex) const
Transform passed 'vertex' by this matrix - converts local frame to parent.
Definition: TGLUtil.cxx:933
TGLVector3 GetScale() const
Get local axis scaling factors.
Definition: TGLUtil.cxx:1099
void MultRight(const TGLMatrix &rhs)
Multiply with matrix rhs on right.
Definition: TGLUtil.cxx:702
void SetTranslation(Double_t x, Double_t y, Double_t z)
Set matrix translation components x,y,z.
Definition: TGLUtil.cxx:776
void MultiplyIP(TGLVector3 &v, Double_t w=1) const
Multiply vector in-place.
Definition: TGLUtil.cxx:1075
void Translate(const TGLVector3 &vect)
Shift matrix translation components by 'vect' in parent frame.
Definition: TGLUtil.cxx:802
void Dump() const
Output 16 matrix components to std::cout.
Definition: TGLUtil.cxx:1132
TGLMatrix()
Construct default identity matrix:
Definition: TGLUtil.cxx:606
3D plane class - of format Ax + By + Cz + D = 0
Definition: TGLUtil.h:525
void Set(const TGLPlane &other)
Assign from other.
Definition: TGLUtil.cxx:425
Double_t B() const
Definition: TGLUtil.h:554
Double_t D() const
Definition: TGLUtil.h:556
void Negate()
Negate the plane.
Definition: TGLUtil.cxx:481
TGLVertex3 NearestOn(const TGLVertex3 &point) const
Return nearest point on plane.
Definition: TGLUtil.cxx:500
Double_t C() const
Definition: TGLUtil.h:555
TGLPlane & operator=(const TGLPlane &src)
Assignment operator.
Definition: TGLUtil.cxx:389
Double_t A() const
Definition: TGLUtil.h:553
void Normalise()
Normalise the plane.
Definition: TGLUtil.cxx:398
TGLPlane()
Construct a default plane of x + y + z = 0.
Definition: TGLUtil.cxx:336
Double_t DistanceTo(const TGLVertex3 &vertex) const
Distance from plane to vertex.
Definition: TGLUtil.cxx:492
TGLVector3 Norm() const
Definition: TGLUtil.h:558
void Dump() const
Output plane equation to std::out.
Definition: TGLUtil.cxx:416
Double_t fVals[4]
Definition: TGLUtil.h:528
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
Bool_t GetXLog() const
Get X log.
const Rgl::Range_t & GetZRange() const
Z range.
Bool_t GetYLog() const
Get Y log.
Bool_t GetZLog() const
Get Z log.
const Rgl::Range_t & GetYRange() const
Y range.
const Rgl::Range_t & GetXRange() const
X range.
Wrapper class for GLU quadric shape drawing object.
Definition: TGLQuadric.h:28
GLUquadric * Get()
Get the internal raw GLU quadric object. Created on first call.
Definition: TGLQuadric.cxx:44
Viewport (pixel base) 2D rectangle class.
Definition: TGLUtil.h:422
Int_t fY
Definition: TGLUtil.h:425
Int_t fWidth
Corner.
Definition: TGLUtil.h:426
TGLRect()
Positive width/height.
Definition: TGLUtil.cxx:229
Int_t Diagonal() const
Return the diagonal of the rectangle.
Definition: TGLUtil.cxx:286
Rgl::EOverlap Overlap(const TGLRect &other) const
Return overlap result (kInside, kOutside, kPartial) of this rect with 'other'.
Definition: TGLUtil.cxx:297
virtual ~TGLRect()
Destroy rect object.
Definition: TGLUtil.cxx:254
Int_t fHeight
Definition: TGLUtil.h:426
void Expand(Int_t x, Int_t y)
Expand the rect to encompass point (x,y)
Definition: TGLUtil.cxx:261
Int_t fX
Definition: TGLUtil.h:425
const UChar_t * GetPixelColor(Int_t px, Int_t py) const
Get pixel color.
Definition: TGLUtil.cxx:2826
void ReadColorBuffer(Int_t width, Int_t height)
Read color buffer.
Definition: TGLUtil.cxx:2802
virtual ~TGLSelectionBuffer()
TGLSelectionBuffer destructor.
Definition: TGLUtil.cxx:2795
TGLSelectionBuffer()
TGLSelectionBuffer constructor.
Definition: TGLUtil.cxx:2787
std::vector< UChar_t > fBuffer
Definition: TGLUtil.h:1134
Wrapper class for various misc static functions - error checking, draw helpers etc.
Definition: TGLUtil.h:879
static void DrawSphere(const TGLVertex3 &position, Double_t radius, const UChar_t rgba[4])
Draw sphere, centered on vertex 'position', with radius 'radius', color 'rgba'.
Definition: TGLUtil.cxx:2351
static void Color4ubv(const UChar_t *rgba)
Wrapper for glColor4ubv.
Definition: TGLUtil.cxx:1773
static UInt_t GetDrawQuality()
static: get draw quality
Definition: TGLUtil.cxx:1599
static Int_t fgPickingRadius
Definition: TGLUtil.h:929
static const UChar_t fgWhite[4]
Definition: TGLUtil.h:1053
static UInt_t fgDefaultDrawQuality
Definition: TGLUtil.h:917
static void SetDrawQuality(UInt_t dq)
static: set draw quality
Definition: TGLUtil.cxx:1607
static Float_t GetPointSizeScale()
Get global point-size scale.
Definition: TGLUtil.cxx:1877
static void Color3f(Float_t r, Float_t g, Float_t b)
Wrapper for glColor3f.
Definition: TGLUtil.cxx:1781
static Float_t fgPointSize
Definition: TGLUtil.h:922
static Float_t fgLineWidth
Definition: TGLUtil.h:923
static Float_t fgScreenScalingFactor
Definition: TGLUtil.h:927
static void ResetDrawQuality()
static: reset draw quality
Definition: TGLUtil.cxx:1615
static Float_t fgPointSizeScale
Definition: TGLUtil.h:924
static Bool_t IsColorLocked()
Returns true if color lock-count is greater than 0.
Definition: TGLUtil.cxx:1683
static void Color3fv(const Float_t *rgb)
Wrapper for glColor3fv.
Definition: TGLUtil.cxx:1797
static void SetLineWidthScale(Float_t scale)
Set global line-width scale.
Definition: TGLUtil.cxx:1901
static UInt_t LockColor()
Prevent further color changes.
Definition: TGLUtil.cxx:1663
static void Color4f(Float_t r, Float_t g, Float_t b, Float_t a)
Wrapper for glColor4f.
Definition: TGLUtil.cxx:1789
static void SetDrawColors(const UChar_t rgba[4])
Set basic draw colors from 4 component 'rgba' Used by other TGLUtil drawing routines.
Definition: TGLUtil.cxx:2330
static void ColorTransparency(Color_t color_index, Char_t transparency=0)
Set color from color_index and ROOT-style transparency (default 0).
Definition: TGLUtil.cxx:1735
static void BeginAttLine(const TAttLine &aline, Char_t transp, Int_t pick_radius=0, Bool_t selection=kFALSE)
Setup drawing parameters according to passed TAttLine.
Definition: TGLUtil.cxx:2266
static const UChar_t fgRed[4]
Definition: TGLUtil.h:1049
static void RenderPolyLine(const TAttLine &aline, Char_t transp, Float_t *p, Int_t n, Int_t pick_radius=0, Bool_t selection=kFALSE)
Render poly-line as specified by the p-array.
Definition: TGLUtil.cxx:2246
static UInt_t GetDefaultDrawQuality()
static: get default draw quality
Definition: TGLUtil.cxx:1623
static void BeginExtendPickRegion(Float_t scale)
Definition: TGLUtil.cxx:1946
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition: TGLUtil.cxx:1576
ELineHeadShape
Definition: TGLUtil.h:948
@ kLineHeadNone
Definition: TGLUtil.h:948
@ kLineHeadBox
Definition: TGLUtil.h:948
@ kLineHeadArrow
Definition: TGLUtil.h:948
static Float_t GetLineWidthScale()
Returns global line-width scale.
Definition: TGLUtil.cxx:1893
static Float_t fgPointLineScalingFactor
Definition: TGLUtil.h:928
static UInt_t UnlockColor()
Allow color changes.
Definition: TGLUtil.cxx:1671
static void EndAttLine(Int_t pick_radius=0, Bool_t selection=kFALSE)
Restore previous line drawing state.
Definition: TGLUtil.cxx:2302
static void DrawLine(const TGLLine3 &line, ELineHeadShape head, Double_t size, const UChar_t rgba[4])
Draw thick line (tube) defined by 'line', with head at end shape 'head' - box/arrow/none,...
Definition: TGLUtil.cxx:2366
static void Color(const TGLColor &color)
Set color from TGLColor.
Definition: TGLUtil.cxx:1691
static void DrawRing(const TGLVertex3 &center, const TGLVector3 &normal, Double_t radius, const UChar_t *rgba)
Draw ring, centered on 'center', lying on plane defined by 'center' & 'normal' of outer radius 'radiu...
Definition: TGLUtil.cxx:2432
static void Color3ubv(const UChar_t *rgb)
Wrapper for glColor3ubv.
Definition: TGLUtil.cxx:1765
static Int_t CheckError(const char *loc)
Check current GL error state, outputting details via ROOT Error method if one.
Definition: TGLUtil.cxx:1640
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition: TGLUtil.cxx:1846
static void ColorAlpha(const TGLColor &color, UChar_t alpha)
Set color from TGLColor and alpha value.
Definition: TGLUtil.cxx:1699
static Int_t GetPickingRadius()
Returns picking radius.
Definition: TGLUtil.cxx:1865
static void SetPointSizeScale(Float_t scale)
Set global point-size scale.
Definition: TGLUtil.cxx:1885
static void Color4fv(const Float_t *rgba)
Wrapper for glColor4fv.
Definition: TGLUtil.cxx:1805
static void Color3ub(UChar_t r, UChar_t g, UChar_t b)
Wrapper for glColor3ub.
Definition: TGLUtil.cxx:1749
static UInt_t fgDrawQuality
Definition: TGLUtil.h:918
static GLUtesselator * GetDrawTesselator4dv()
Returns a tesselator for direct drawing when using 4-vertices with double precision.
Definition: TGLUtil.cxx:1555
static const UChar_t fgBlue[4]
Definition: TGLUtil.h:1051
static const UChar_t fgGrey[4]
Definition: TGLUtil.h:1054
@ kAxesNone
Definition: TGLUtil.h:949
@ kAxesOrigin
Definition: TGLUtil.h:949
static Float_t PointSize()
Get the point-size, taking the global scaling into account.
Definition: TGLUtil.cxx:1929
static void EndExtendPickRegion()
Definition: TGLUtil.cxx:1961
static GLUtesselator * GetDrawTesselator3dv()
Returns a tesselator for direct drawing when using 3-vertices with double precision.
Definition: TGLUtil.cxx:1534
static GLUtesselator * GetDrawTesselator4fv()
Returns a tesselator for direct drawing when using 4-vertices with single precision.
Definition: TGLUtil.cxx:1513
static const UChar_t fgGreen[4]
Definition: TGLUtil.h:1050
static UInt_t fgColorLockCount
Definition: TGLUtil.h:920
static GLUtesselator * GetDrawTesselator3fv()
Returns a tesselator for direct drawing when using 3-vertices with single precision.
Definition: TGLUtil.cxx:1492
static void SetDefaultDrawQuality(UInt_t dq)
static: set default draw quality
Definition: TGLUtil.cxx:1631
static void PointToViewport(Int_t &x, Int_t &y)
Convert from point/screen coordinates to GL viewport coordinates.
Definition: TGLUtil.cxx:1817
static void DrawReferenceMarker(const TGLCamera &camera, const TGLVertex3 &pos, Float_t radius=3, const UChar_t *rgba=0)
Draw a sphere- marker on world-coordinate 'pos' with pixel radius 'radius'.
Definition: TGLUtil.cxx:2473
static void DrawNumber(const TString &num, const TGLVertex3 &pos, Bool_t center=kFALSE)
Draw number in string 'num' via internal 8x8-pixel bitmap on vertex 'pos'.
Definition: TGLUtil.cxx:2628
static Float_t LineWidth()
Get the line-width, taking the global scaling into account.
Definition: TGLUtil.cxx:1937
static Float_t fgLineWidthScale
Definition: TGLUtil.h:925
static void RenderPolyMarkers(const TAttMarker &marker, Char_t transp, Float_t *p, Int_t n, Int_t pick_radius=0, Bool_t selection=kFALSE, Bool_t sec_selection=kFALSE)
Render polymarkers at points specified by p-array.
Definition: TGLUtil.cxx:1974
static void DrawSimpleAxes(const TGLCamera &camera, const TGLBoundingBox &bbox, Int_t axesType)
Draw simple xyz-axes for given bounding-box.
Definition: TGLUtil.cxx:2488
static const UChar_t fgYellow[4]
Definition: TGLUtil.h:1052
static void RenderPoints(const TAttMarker &marker, Float_t *p, Int_t n, Int_t pick_radius=0, Bool_t selection=kFALSE, Bool_t sec_selection=kFALSE)
Render markers as circular or square points.
Definition: TGLUtil.cxx:2014
static Float_t GetPointLineScalingFactor()
Return extra scaling factor for points and lines.
Definition: TGLUtil.cxx:1857
static void Color4ub(UChar_t r, UChar_t g, UChar_t b, UChar_t a)
Wrapper for glColor4ub.
Definition: TGLUtil.cxx:1757
static void RenderCrosses(const TAttMarker &marker, Float_t *p, Int_t n, Bool_t sec_selection=kFALSE)
Render markers as crosses.
Definition: TGLUtil.cxx:2134
3 component (x/y/z) vector class.
Definition: TGLUtil.h:248
Double_t Mag() const
Definition: TGLUtil.h:298
TGLVector3()=default
void Normalise()
Definition: TGLUtil.h:304
3 component (x/y/z) vertex class.
Definition: TGLUtil.h:84
void Dump() const
Output vertex component values to std::cout.
Definition: TGLUtil.cxx:130
void Minimum(const TGLVertex3 &other)
Definition: TGLUtil.cxx:111
Double_t X() const
Definition: TGLUtil.h:119
Double_t Z() const
Definition: TGLUtil.h:123
Double_t fVals[3]
Definition: TGLUtil.h:88
void Maximum(const TGLVertex3 &other)
Definition: TGLUtil.cxx:120
void Fill(Double_t val)
Definition: TGLUtil.h:204
void Set(Double_t x, Double_t y, Double_t z)
Definition: TGLUtil.h:210
Double_t Y() const
Definition: TGLUtil.h:121
TGLVertex3()
Construct a default (0.0, 0.0, 0.0) vertex.
Definition: TGLUtil.cxx:53
void Shift(TGLVector3 &shift)
Offset a vertex by vector 'shift'.
Definition: TGLUtil.cxx:92
const Double_t * CArr() const
Definition: TGLUtil.h:126
~TGLVertex3()
Destroy vertex object.
Definition: TGLUtil.cxx:85
The axis painter class.
Definition: TGaxis.h:23
void SetTimeFormat(const char *tformat)
Change the format used for time plotting.
Definition: TGaxis.cxx:2760
virtual void PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, Double_t &wmin, Double_t &wmax, Int_t &ndiv, Option_t *chopt="", Double_t gridlength=0, Bool_t drawGridOnly=kFALSE)
Control function to draw an axis.
Definition: TGaxis.cxx:975
void SetLabelOffset(Float_t labeloffset)
Definition: TGaxis.h:106
virtual void ImportAxisAttributes(TAxis *axis)
Internal method to import TAxis attributes to this TGaxis.
Definition: TGaxis.cxx:925
void SetOption(Option_t *option="")
To set axis options.
Definition: TGaxis.cxx:2725
static void Optimize(Double_t A1, Double_t A2, Int_t nold, Double_t &BinLow, Double_t &BinHigh, Int_t &nbins, Double_t &BWID, Option_t *option="")
Static function to compute reasonable axis limits.
Basic string class.
Definition: TString.h:136
Ssiz_t Length() const
Definition: TString.h:410
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2336
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:1056
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:1122
TLine * line
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
return c1
Definition: legend1.C:41
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
return c2
Definition: legend2.C:14
return c3
Definition: legend3.C:15
void swap(RDirectoryEntry &e1, RDirectoryEntry &e2) noexcept
static double B[]
static double C[]
double T(double x)
Definition: ChebyshevPol.h:34
void DrawTrapezoid(const Double_t ver[][2], Double_t zMin, Double_t zMax, Bool_t color=kTRUE)
Definition: TGLUtil.cxx:3348
void DrawFaceTextured(const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, Double_t t1, Double_t t2, Double_t t3, const TGLVector3 &norm1, const TGLVector3 &norm2, const TGLVector3 &norm3)
Draw textured triangle.
Definition: TGLUtil.cxx:3836
void DrawQuadStripWithRadialGradientFill(unsigned nPoints, const Double_t *inner, const Double_t *innerRGBA, const Double_t *outer, const Double_t *outerRGBA)
TODO: is it possible to use GLdouble to avoid problems with Double_t/GLdouble if they are not the sam...
Definition: TGLUtil.cxx:3217
void DrawQuadFilled(const TGLVertex3 &v0, const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVector3 &normal)
Draw quad face.
Definition: TGLUtil.cxx:2953
void DrawTrapezoidTextured(const Double_t ver[][2], Double_t zMin, Double_t zMax, Double_t tMin, Double_t tMax)
In polar coordinates, box became trapezoid.
Definition: TGLUtil.cxx:3418
const Float_t gNullEmission[]
Definition: TGLUtil.cxx:2847
const Int_t gFramePoints[][2]
Definition: TGLUtil.cxx:3750
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2891
const Float_t gBlueEmission[]
Definition: TGLUtil.cxx:2843
const Float_t gWhiteEmission[]
Definition: TGLUtil.cxx:2845
void SetZLevels(TAxis *zAxis, Double_t zMin, Double_t zMax, Double_t zScale, std::vector< Double_t > &zLevels)
Definition: TGLUtil.cxx:3820
void CylindricalNormalInv(const Double_t *v, Double_t *normal)
Definition: TGLUtil.cxx:3334
void DrawTrapezoidTextured2(const Double_t ver[][2], Double_t zMin, Double_t zMax, Double_t tMin, Double_t tMax)
In polar coordinates, box became trapezoid.
Definition: TGLUtil.cxx:3495
const Int_t gBoxFrontQuads[][4]
Definition: TGLUtil.cxx:2996
const Float_t gGrayEmission[]
Definition: TGLUtil.cxx:2846
void GetColor(Float_t v, Float_t vmin, Float_t vmax, Int_t type, Float_t *rgba)
This function creates color for parametric surface's vertex, using its 'u' value.
Definition: TGLUtil.cxx:3877
const Int_t gBoxBackQuads[][4]
Definition: TGLUtil.cxx:3000
void SphericalNormal(const Double_t *v, Double_t *normal)
Definition: TGLUtil.cxx:3559
void DrawCylinder(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax)
Cylinder for lego3.
Definition: TGLUtil.cxx:3244
const Int_t gAxisType[][2]
Definition: TGLUtil.cxx:3752
void DrawError(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax)
Definition: TGLUtil.cxx:3298