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();
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
1426
1429
1430const UChar_t TGLUtil::fgRed[4] = { 230, 0, 0, 255 };
1431const UChar_t TGLUtil::fgGreen[4] = { 0, 230, 0, 255 };
1432const UChar_t TGLUtil::fgBlue[4] = { 0, 0, 230, 255 };
1433const UChar_t TGLUtil::fgYellow[4] = { 210, 210, 0, 255 };
1434const UChar_t TGLUtil::fgWhite[4] = { 255, 255, 255, 255 };
1435const UChar_t TGLUtil::fgGrey[4] = { 128, 128, 128, 100 };
1436
1437#ifndef CALLBACK
1438#define CALLBACK
1439#endif
1440
1441extern "C"
1442{
1443#if defined(__APPLE_CC__) && __APPLE_CC__ > 4000 && __APPLE_CC__ < 5450 && !defined(__INTEL_COMPILER)
1444 typedef GLvoid (*tessfuncptr_t)(...);
1445#elif defined(__linux__) || defined(__FreeBSD__) || defined( __OpenBSD__ ) || defined(__sun) || defined (__CYGWIN__) || defined (__APPLE__)
1446 typedef GLvoid (*tessfuncptr_t)();
1447#elif defined (WIN32)
1448 typedef GLvoid (CALLBACK *tessfuncptr_t)();
1449#else
1450 #error "Error - need to define type tessfuncptr_t for this platform/compiler"
1451#endif
1452}
1453
1454namespace
1455{
1456
1457class TGLTesselatorWrap
1458{
1459protected:
1460
1461public:
1462 GLUtesselator *fTess;
1463
1464 TGLTesselatorWrap(tessfuncptr_t vertex_func) : fTess(0)
1465 {
1466 fTess = gluNewTess();
1467 if (!fTess)
1468 throw std::bad_alloc();
1469
1470#if defined(__GNUC__) && __GNUC__ >= 8
1471#pragma GCC diagnostic push
1472#pragma GCC diagnostic ignored "-Wcast-function-type"
1473#endif
1474
1475 gluTessCallback(fTess, (GLenum)GLU_BEGIN, (tessfuncptr_t) glBegin);
1476 gluTessCallback(fTess, (GLenum)GLU_END, (tessfuncptr_t) glEnd);
1477 gluTessCallback(fTess, (GLenum)GLU_VERTEX, vertex_func);
1478
1479#if defined(__GNUC__) && __GNUC__ >= 8
1480#pragma GCC diagnostic pop
1481#endif
1482
1483 }
1484
1485 virtual ~TGLTesselatorWrap()
1486 {
1487 if (fTess)
1488 gluDeleteTess(fTess);
1489 }
1490};
1491
1492}
1493
1494////////////////////////////////////////////////////////////////////////////////
1495/// Returns a tesselator for direct drawing when using 3-vertices with
1496/// single precision.
1497
1499{
1500
1501#if defined(__GNUC__) && __GNUC__ >= 8
1502#pragma GCC diagnostic push
1503#pragma GCC diagnostic ignored "-Wcast-function-type"
1504#endif
1505
1506 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex3fv);
1507
1508#if defined(__GNUC__) && __GNUC__ >= 8
1509#pragma GCC diagnostic pop
1510#endif
1511
1512 return singleton.fTess;
1513}
1514
1515////////////////////////////////////////////////////////////////////////////////
1516/// Returns a tesselator for direct drawing when using 4-vertices with
1517/// single precision.
1518
1520{
1521
1522#if defined(__GNUC__) && __GNUC__ >= 8
1523#pragma GCC diagnostic push
1524#pragma GCC diagnostic ignored "-Wcast-function-type"
1525#endif
1526
1527 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex4fv);
1528
1529#if defined(__GNUC__) && __GNUC__ >= 8
1530#pragma GCC diagnostic pop
1531#endif
1532
1533 return singleton.fTess;
1534}
1535
1536////////////////////////////////////////////////////////////////////////////////
1537/// Returns a tesselator for direct drawing when using 3-vertices with
1538/// double precision.
1539
1541{
1542
1543#if defined(__GNUC__) && __GNUC__ >= 8
1544#pragma GCC diagnostic push
1545#pragma GCC diagnostic ignored "-Wcast-function-type"
1546#endif
1547
1548 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex3dv);
1549
1550#if defined(__GNUC__) && __GNUC__ >= 8
1551#pragma GCC diagnostic pop
1552#endif
1553
1554 return singleton.fTess;
1555}
1556
1557////////////////////////////////////////////////////////////////////////////////
1558/// Returns a tesselator for direct drawing when using 4-vertices with
1559/// double precision.
1560
1562{
1563
1564#if defined(__GNUC__) && __GNUC__ >= 8
1565#pragma GCC diagnostic push
1566#pragma GCC diagnostic ignored "-Wcast-function-type"
1567#endif
1568
1569 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex4dv);
1570
1571#if defined(__GNUC__) && __GNUC__ >= 8
1572#pragma GCC diagnostic pop
1573#endif
1574
1575 return singleton.fTess;
1576}
1577
1578////////////////////////////////////////////////////////////////////////////////
1579/// Initialize globals that require other libraries to be initialized.
1580/// This is called from TGLWidget creation function.
1581
1583{
1584 static Bool_t init_done = kFALSE;
1585 if (init_done) return;
1586 init_done = kTRUE;
1587
1588 fgScreenScalingFactor = gVirtualX->GetOpenGLScalingFactor();
1589
1590 if (strcmp(gEnv->GetValue("OpenGL.PointLineScalingFactor", "native"), "native") == 0)
1591 {
1593 }
1594 else
1595 {
1596 fgPointLineScalingFactor = gEnv->GetValue("OpenGL.PointLineScalingFactor", 1.0);
1597 }
1598
1599 fgPickingRadius = TMath::Nint(gEnv->GetValue("OpenGL.PickingRadius", 3.0) * TMath::Sqrt(fgScreenScalingFactor));
1600}
1601
1602////////////////////////////////////////////////////////////////////////////////
1603///static: get draw quality
1604
1606{
1607 return fgDrawQuality;
1608}
1609
1610////////////////////////////////////////////////////////////////////////////////
1611///static: set draw quality
1612
1614{
1615 fgDrawQuality = dq;
1616}
1617
1618////////////////////////////////////////////////////////////////////////////////
1619///static: reset draw quality
1620
1622{
1624}
1625
1626////////////////////////////////////////////////////////////////////////////////
1627///static: get default draw quality
1628
1630{
1631 return fgDefaultDrawQuality;
1632}
1633
1634////////////////////////////////////////////////////////////////////////////////
1635///static: set default draw quality
1636
1638{
1640}
1641
1642////////////////////////////////////////////////////////////////////////////////
1643/// Check current GL error state, outputting details via ROOT
1644/// Error method if one
1645
1647{
1648 GLenum errCode;
1649 const GLubyte *errString;
1650
1651 if ((errCode = glGetError()) != GL_NO_ERROR) {
1652 errString = gluErrorString(errCode);
1653 if (loc) {
1654 Error(loc, "GL Error %s", (const char *)errString);
1655 } else {
1656 Error("TGLUtil::CheckError", "GL Error %s", (const char *)errString);
1657 }
1658 }
1659 return errCode;
1660}
1661
1662/******************************************************************************/
1663// Color wrapping functions
1664/******************************************************************************/
1665
1666////////////////////////////////////////////////////////////////////////////////
1667/// Prevent further color changes.
1668
1670{
1671 return ++fgColorLockCount;
1672}
1673
1674////////////////////////////////////////////////////////////////////////////////
1675/// Allow color changes.
1676
1678{
1679 if (fgColorLockCount)
1681 else
1682 Error("TGLUtil::UnlockColor", "fgColorLockCount already 0.");
1683 return fgColorLockCount;
1684}
1685
1686////////////////////////////////////////////////////////////////////////////////
1687/// Returns true if color lock-count is greater than 0.
1688
1690{
1691 return fgColorLockCount > 0;
1692}
1693
1694////////////////////////////////////////////////////////////////////////////////
1695/// Set color from TGLColor.
1696
1697void TGLUtil::Color(const TGLColor& color)
1698{
1699 if (fgColorLockCount == 0) glColor4ubv(color.CArr());
1700}
1701
1702////////////////////////////////////////////////////////////////////////////////
1703/// Set color from TGLColor and alpha value.
1704
1705void TGLUtil::ColorAlpha(const TGLColor& color, UChar_t alpha)
1706{
1707 if (fgColorLockCount == 0)
1708 {
1709 glColor4ub(color.GetRed(), color.GetGreen(), color.GetBlue(), alpha);
1710 }
1711}
1712
1713////////////////////////////////////////////////////////////////////////////////
1714/// Set color from TGLColor and alpha value.
1715
1716void TGLUtil::ColorAlpha(const TGLColor& color, Float_t alpha)
1717{
1718 if (fgColorLockCount == 0)
1719 {
1720 glColor4ub(color.GetRed(), color.GetGreen(), color.GetBlue(), (UChar_t)(255*alpha));
1721 }
1722}
1723
1724////////////////////////////////////////////////////////////////////////////////
1725/// Set color from color_index and GL-style alpha (default 1).
1726
1727void TGLUtil::ColorAlpha(Color_t color_index, Float_t alpha)
1728{
1729 if (fgColorLockCount == 0) {
1730 if (color_index < 0)
1731 color_index = 1;
1732 TColor* c = gROOT->GetColor(color_index);
1733 if (c)
1734 glColor4f(c->GetRed(), c->GetGreen(), c->GetBlue(), alpha);
1735 }
1736}
1737
1738////////////////////////////////////////////////////////////////////////////////
1739/// Set color from color_index and ROOT-style transparency (default 0).
1740
1741void TGLUtil::ColorTransparency(Color_t color_index, Char_t transparency)
1742{
1743 if (fgColorLockCount == 0) {
1744 if (color_index < 0)
1745 color_index = 1;
1746 TColor* c = gROOT->GetColor(color_index);
1747 if (c)
1748 glColor4f(c->GetRed(), c->GetGreen(), c->GetBlue(), 1.0f - 0.01f*transparency);
1749 }
1750}
1751
1752////////////////////////////////////////////////////////////////////////////////
1753/// Wrapper for glColor3ub.
1754
1756{
1757 if (fgColorLockCount == 0) glColor3ub(r, g, b);
1758}
1759
1760////////////////////////////////////////////////////////////////////////////////
1761/// Wrapper for glColor4ub.
1762
1764{
1765 if (fgColorLockCount == 0) glColor4ub(r, g, b, a);
1766}
1767
1768////////////////////////////////////////////////////////////////////////////////
1769/// Wrapper for glColor3ubv.
1770
1772{
1773 if (fgColorLockCount == 0) glColor3ubv(rgb);
1774}
1775
1776////////////////////////////////////////////////////////////////////////////////
1777/// Wrapper for glColor4ubv.
1778
1780{
1781 if (fgColorLockCount == 0) glColor4ubv(rgba);
1782}
1783
1784////////////////////////////////////////////////////////////////////////////////
1785/// Wrapper for glColor3f.
1786
1788{
1789 if (fgColorLockCount == 0) glColor3f(r, g, b);
1790}
1791
1792////////////////////////////////////////////////////////////////////////////////
1793/// Wrapper for glColor4f.
1794
1796{
1797 if (fgColorLockCount == 0) glColor4f(r, g, b, a);
1798}
1799
1800////////////////////////////////////////////////////////////////////////////////
1801/// Wrapper for glColor3fv.
1802
1804{
1805 if (fgColorLockCount == 0) glColor3fv(rgb);
1806}
1807
1808////////////////////////////////////////////////////////////////////////////////
1809/// Wrapper for glColor4fv.
1810
1812{
1813 if (fgColorLockCount == 0) glColor4fv(rgba);
1814}
1815
1816/******************************************************************************/
1817// Coordinate conversion and extra scaling (needed for osx retina)
1818/******************************************************************************/
1819
1820////////////////////////////////////////////////////////////////////////////////
1821/// Convert from point/screen coordinates to GL viewport coordinates.
1822
1824{
1825 if (fgScreenScalingFactor != 1.0)
1826 {
1829 }
1830}
1831
1832////////////////////////////////////////////////////////////////////////////////
1833/// Convert from point/screen coordinates to GL viewport coordinates.
1834
1836{
1837 if (fgScreenScalingFactor != 1.0)
1838 {
1843 }
1844}
1845
1846////////////////////////////////////////////////////////////////////////////////
1847/// Returns scaling factor between screen points and GL viewport pixels.
1848/// This is what is returned by gVirtualX->GetOpenGLScalingFactor() but is
1849/// cached here to avoid a virtual function call as it is used quite often in
1850/// TGLPhysical shape when drawing the selection highlight.
1851
1853{
1854 return fgScreenScalingFactor;
1855}
1856
1857////////////////////////////////////////////////////////////////////////////////
1858/// Return extra scaling factor for points and lines.
1859/// By default this is set to the same value as ScreenScalingFactor to keep
1860/// the same appearance. To override use rootrc entry, e.g.:
1861/// OpenGL.PointLineScalingFactor: 1.0
1862
1864{
1866}
1867
1868////////////////////////////////////////////////////////////////////////////////
1869/// Returns picking radius.
1870
1872{
1873 return fgPickingRadius;
1874}
1875
1876/******************************************************************************/
1877// Control for scaling of point-size and line-width.
1878/******************************************************************************/
1879
1880////////////////////////////////////////////////////////////////////////////////
1881/// Get global point-size scale.
1882
1884{
1885 return fgPointSizeScale;
1886}
1887
1888////////////////////////////////////////////////////////////////////////////////
1889/// Set global point-size scale.
1890
1892{
1893 fgPointSizeScale = scale;
1894}
1895
1896////////////////////////////////////////////////////////////////////////////////
1897/// Returns global line-width scale.
1898
1900{
1901 return fgLineWidthScale;
1902}
1903
1904////////////////////////////////////////////////////////////////////////////////
1905/// Set global line-width scale.
1906
1908{
1909 fgLineWidthScale = scale;
1910}
1911
1912////////////////////////////////////////////////////////////////////////////////
1913/// Set the point-size, taking the global scaling into account.
1914/// Wrapper for glPointSize.
1915
1917{
1919 glPointSize(fgPointSize);
1920}
1921
1922////////////////////////////////////////////////////////////////////////////////
1923/// Set the line-width, taking the global scaling into account.
1924/// Wrapper for glLineWidth.
1925
1927{
1929 glLineWidth(fgLineWidth);
1930}
1931
1932////////////////////////////////////////////////////////////////////////////////
1933/// Get the point-size, taking the global scaling into account.
1934
1936{
1937 return fgPointSize;
1938}
1939
1940////////////////////////////////////////////////////////////////////////////////
1941/// Get the line-width, taking the global scaling into account.
1942
1944{
1945 return fgLineWidth;
1946}
1947
1948/******************************************************************************/
1949// Rendering of polymarkers and lines from logical-shapes.
1950/******************************************************************************/
1951
1953{
1954 // Extend pick region for large point-sizes or line-widths.
1955
1956 glMatrixMode(GL_PROJECTION);
1957 glPushMatrix();
1958 Float_t pm[16];
1959 glGetFloatv(GL_PROJECTION_MATRIX, pm);
1960 for (Int_t i=0; i<=12; i+=4) {
1961 pm[i] *= scale; pm[i+1] *= scale;
1962 }
1963 glLoadMatrixf(pm);
1964 glMatrixMode(GL_MODELVIEW);
1965}
1966
1968{
1969 // End extension of the pick region.
1970
1971 glMatrixMode(GL_PROJECTION);
1972 glPopMatrix();
1973 glMatrixMode(GL_MODELVIEW);
1974}
1975
1976////////////////////////////////////////////////////////////////////////////////
1977/// Render polymarkers at points specified by p-array.
1978/// Supports point and cross-like styles.
1979
1981 Float_t* p, Int_t n,
1982 Int_t pick_radius, Bool_t selection,
1983 Bool_t sec_selection)
1984{
1985 if (n == 0) return;
1986
1987 glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT | GL_LINE_BIT);
1988
1989 glDisable(GL_LIGHTING);
1991
1992 Int_t s = marker.GetMarkerStyle();
1993 if (s == 2 || s == 3 || s == 5 || s == 28)
1994 RenderCrosses(marker, p, n, sec_selection);
1995 else
1996 RenderPoints(marker, p, n, pick_radius, selection, sec_selection);
1997
1998 glPopAttrib();
1999}
2000
2001////////////////////////////////////////////////////////////////////////////////
2002/// Render polymarkers at points specified by p-array.
2003/// Supports point and cross-like styles.
2004/// Color is set externally. Lighting is disabled externally.
2005
2006void TGLUtil::RenderPolyMarkers(const TAttMarker &marker, const std::vector<Double_t> &points,
2007 Double_t dX, Double_t dY, Double_t dZ)
2008{
2009 const Int_t s = marker.GetMarkerStyle();
2010 if (s == 2 || s == 3 || s == 5 || s == 28)
2011 RenderCrosses(marker, points, dX, dY, dZ);
2012 else
2013 RenderPoints(marker, points);
2014}
2015
2016////////////////////////////////////////////////////////////////////////////////
2017/// Render markers as circular or square points.
2018/// Color is never changed.
2019
2021 Float_t* op, Int_t n,
2022 Int_t pick_radius, Bool_t selection,
2023 Bool_t sec_selection)
2024{
2025 Int_t style = marker.GetMarkerStyle();
2026 Float_t size = 5*marker.GetMarkerSize();
2027 if (style == 4 || style == 20 || style == 24)
2028 {
2029 glEnable(GL_POINT_SMOOTH);
2030 if (style == 4 || style == 24) {
2031 glEnable(GL_BLEND);
2032 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2033 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
2034 }
2035 }
2036 else
2037 {
2038 glDisable(GL_POINT_SMOOTH);
2039 if (style == 1) size = 1;
2040 else if (style == 6) size = 2;
2041 else if (style == 7) size = 3;
2042 }
2044
2045 // During selection extend picking region for large point-sizes.
2046 Bool_t changePM = selection && PointSize() > pick_radius;
2047 if (changePM)
2048 BeginExtendPickRegion((Float_t) pick_radius / PointSize());
2049
2050 Float_t* p = op;
2051 if (sec_selection)
2052 {
2053 glPushName(0);
2054 for (Int_t i=0; i<n; ++i, p+=3)
2055 {
2056 glLoadName(i);
2057 glBegin(GL_POINTS);
2058 glVertex3fv(p);
2059 glEnd();
2060 }
2061 glPopName();
2062 }
2063 else
2064 {
2065 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
2066 glVertexPointer(3, GL_FLOAT, 0, p);
2067 glEnableClientState(GL_VERTEX_ARRAY);
2068 { // Circumvent bug in ATI's linux drivers.
2069 Int_t nleft = n;
2070 Int_t ndone = 0;
2071 const Int_t maxChunk = 8192;
2072 while (nleft > maxChunk)
2073 {
2074 glDrawArrays(GL_POINTS, ndone, maxChunk);
2075 nleft -= maxChunk;
2076 ndone += maxChunk;
2077 }
2078 glDrawArrays(GL_POINTS, ndone, nleft);
2079 }
2080 glPopClientAttrib();
2081 }
2082
2083 if (changePM)
2085}
2086
2087////////////////////////////////////////////////////////////////////////////////
2088/// Render markers as circular or square points.
2089/// Color is never changed.
2090
2091void TGLUtil::RenderPoints(const TAttMarker& marker, const std::vector<Double_t> &points)
2092{
2093 const Int_t style = marker.GetMarkerStyle();
2094 Float_t size = 5 * marker.GetMarkerSize();
2095
2096 if (style == 4 || style == 20 || style == 24)
2097 {
2098 glEnable(GL_POINT_SMOOTH);
2099 if (style == 4 || style == 24) {
2100 glEnable(GL_BLEND);
2101 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2102 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
2103 }
2104 }
2105 else
2106 {
2107 glDisable(GL_POINT_SMOOTH);
2108 if (style == 1) size = 1;
2109 else if (style == 6) size = 2;
2110 else if (style == 7) size = 3;
2111 }
2112
2113 glPointSize(size);
2114
2115 glVertexPointer(3, GL_DOUBLE, 0, &points[0]);
2116 glEnableClientState(GL_VERTEX_ARRAY);
2117
2118 // Circumvent bug in ATI's linux drivers.
2119 Int_t nleft = points.size() / 3;
2120 Int_t ndone = 0;
2121 const Int_t maxChunk = 8192;
2122 while (nleft > maxChunk)
2123 {
2124 glDrawArrays(GL_POINTS, ndone, maxChunk);
2125 nleft -= maxChunk;
2126 ndone += maxChunk;
2127 }
2128
2129 if (nleft > 0)
2130 glDrawArrays(GL_POINTS, ndone, nleft);
2131
2132 glDisableClientState(GL_VERTEX_ARRAY);
2133 glPointSize(1.f);
2134}
2135
2136////////////////////////////////////////////////////////////////////////////////
2137/// Render markers as crosses.
2138/// Color is never changed.
2139
2141 Float_t* op, Int_t n,
2142 Bool_t sec_selection)
2143{
2144 if (marker.GetMarkerStyle() == 28)
2145 {
2146 glEnable(GL_BLEND);
2147 glEnable(GL_LINE_SMOOTH);
2149 }
2150 else
2151 {
2152 glDisable(GL_LINE_SMOOTH);
2154 }
2155
2156 // cross dim
2157 const Float_t d = 2*marker.GetMarkerSize();
2158 Float_t* p = op;
2159 if (sec_selection)
2160 {
2161 glPushName(0);
2162 for (Int_t i=0; i<n; ++i, p+=3)
2163 {
2164 glLoadName(i);
2165 glBegin(GL_LINES);
2166 glVertex3f(p[0]-d, p[1], p[2]); glVertex3f(p[0]+d, p[1], p[2]);
2167 glVertex3f(p[0], p[1]-d, p[2]); glVertex3f(p[0], p[1]+d, p[2]);
2168 glVertex3f(p[0], p[1], p[2]-d); glVertex3f(p[0], p[1], p[2]+d);
2169 glEnd();
2170 }
2171 glPopName();
2172 }
2173 else
2174 {
2175 glBegin(GL_LINES);
2176 for (Int_t i=0; i<n; ++i, p+=3)
2177 {
2178 glVertex3f(p[0]-d, p[1], p[2]); glVertex3f(p[0]+d, p[1], p[2]);
2179 glVertex3f(p[0], p[1]-d, p[2]); glVertex3f(p[0], p[1]+d, p[2]);
2180 glVertex3f(p[0], p[1], p[2]-d); glVertex3f(p[0], p[1], p[2]+d);
2181 }
2182 glEnd();
2183 }
2184
2185 // Anti-flickering -- when crosses get too small they
2186 // appear / disappear randomly.
2187 {
2188 glDisable(GL_POINT_SMOOTH);
2190
2191 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
2192 glVertexPointer(3, GL_FLOAT, 0, op);
2193 glEnableClientState(GL_VERTEX_ARRAY);
2194 { // Circumvent bug in ATI's linux drivers.
2195 Int_t nleft = n;
2196 Int_t ndone = 0;
2197 const Int_t maxChunk = 8192;
2198 while (nleft > maxChunk)
2199 {
2200 glDrawArrays(GL_POINTS, ndone, maxChunk);
2201 nleft -= maxChunk;
2202 ndone += maxChunk;
2203 }
2204 glDrawArrays(GL_POINTS, ndone, nleft);
2205 }
2206 glPopClientAttrib();
2207 }
2208}
2209
2210////////////////////////////////////////////////////////////////////////////////
2211/// Render markers as crosses.
2212/// Color is never changed.
2213
2214void TGLUtil::RenderCrosses(const TAttMarker& marker, const std::vector<Double_t> &points,
2215 Double_t dX, Double_t dY, Double_t dZ)
2216{
2217 if (marker.GetMarkerStyle() == 28)
2218 {
2219 glEnable(GL_BLEND);
2220 glEnable(GL_LINE_SMOOTH);
2221 glLineWidth(2.f);
2222 }
2223 else
2224 {
2225 glDisable(GL_LINE_SMOOTH);
2226 glLineWidth(1.f);
2227 }
2228
2229 typedef std::vector<Double_t>::size_type size_type;
2230
2231 glBegin(GL_LINES);
2232
2233 for (size_type i = 0; i < points.size(); i += 3) {
2234 const Double_t *p = &points[i];
2235 glVertex3f(p[0] - dX, p[1], p[2]); glVertex3f(p[0] + dX, p[1], p[2]);
2236 glVertex3f(p[0], p[1] - dY, p[2]); glVertex3f(p[0], p[1] + dY, p[2]);
2237 glVertex3f(p[0], p[1], p[2] - dZ); glVertex3f(p[0], p[1], p[2] + dZ);
2238 }
2239
2240 glEnd();
2241
2242 if (marker.GetMarkerStyle() == 28) {
2243 glDisable(GL_LINE_SMOOTH);
2244 glDisable(GL_BLEND);
2245 glLineWidth(1.f);
2246 }
2247}
2248
2249////////////////////////////////////////////////////////////////////////////////
2250/// Render poly-line as specified by the p-array.
2251
2252void TGLUtil::RenderPolyLine(const TAttLine& aline, Char_t transp,
2253 Float_t* p, Int_t n,
2254 Int_t pick_radius, Bool_t selection)
2255{
2256 if (n == 0) return;
2257
2258 BeginAttLine(aline, transp, pick_radius, selection);
2259
2260 Float_t* tp = p;
2261 glBegin(GL_LINE_STRIP);
2262 for (Int_t i=0; i<n; ++i, tp+=3)
2263 glVertex3fv(tp);
2264 glEnd();
2265
2266 EndAttLine(pick_radius, selection);
2267}
2268
2269////////////////////////////////////////////////////////////////////////////////
2270/// Setup drawing parameters according to passed TAttLine.
2271
2272void TGLUtil::BeginAttLine(const TAttLine& aline, Char_t transp,
2273 Int_t pick_radius, Bool_t selection)
2274{
2275 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
2276
2277 glDisable(GL_LIGHTING);
2280 if (aline.GetLineStyle() > 1)
2281 {
2282 // Int_t fac = 1;
2283 UShort_t pat = 0xffff;
2284 switch (aline.GetLineStyle()) {
2285 case 2: pat = 0x3333; break;
2286 case 3: pat = 0x5555; break;
2287 case 4: pat = 0xf040; break;
2288 case 5: pat = 0xf4f4; break;
2289 case 6: pat = 0xf111; break;
2290 case 7: pat = 0xf0f0; break;
2291 case 8: pat = 0xff11; break;
2292 case 9: pat = 0x3fff; break;
2293 case 10: pat = 0x08ff; /* fac = 2; */ break;
2294 }
2295
2296 glLineStipple(1, pat);
2297 glEnable(GL_LINE_STIPPLE);
2298 }
2299
2300 // During selection extend picking region for large line-widths.
2301 if (selection && TGLUtil::LineWidth() > pick_radius)
2303}
2304
2305////////////////////////////////////////////////////////////////////////////////
2306/// Restore previous line drawing state.
2307
2308void TGLUtil::EndAttLine(Int_t pick_radius, Bool_t selection)
2309{
2310 if (selection && TGLUtil::LineWidth() > pick_radius)
2312
2313 glPopAttrib();
2314}
2315
2316/******************************************************************************/
2317// Rendering atoms used by TGLViewer / TGScene.
2318/******************************************************************************/
2319
2320////////////////////////////////////////////////////////////////////////////////
2321/// Set basic draw colors from 4 component 'rgba'
2322/// Used by other TGLUtil drawing routines
2323///
2324/// Sets basic (unlit) color - glColor
2325/// and also GL materials (see OpenGL docs) thus:
2326///
2327/// diffuse : rgba
2328/// ambient : 0.0 0.0 0.0 1.0
2329/// specular : 0.6 0.6 0.6 1.0
2330/// emission : rgba/4.0
2331/// shininess: 60.0
2332///
2333/// emission is set so objects with no lights (but lighting still enabled)
2334/// are partially visible
2335
2337{
2338
2339 // Util function to setup GL color for both unlit and lit material
2340 Float_t rgba[4] = {rgbai[0]/255.f, rgbai[1]/255.f, rgbai[2]/255.f, rgbai[3]/255.f};
2341 Float_t ambient[4] = {0.0, 0.0, 0.0, 1.0};
2342 Float_t specular[4] = {0.6, 0.6, 0.6, 1.0};
2343 Float_t emission[4] = {rgba[0]/4.f, rgba[1]/4.f, rgba[2]/4.f, rgba[3]};
2344
2345 glColor4fv(rgba);
2346 glMaterialfv(GL_FRONT, GL_DIFFUSE, rgba);
2347 glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
2348 glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
2349 glMaterialfv(GL_FRONT, GL_EMISSION, emission);
2350 glMaterialf(GL_FRONT, GL_SHININESS, 60.0);
2351}
2352
2353////////////////////////////////////////////////////////////////////////////////
2354/// Draw sphere, centered on vertex 'position', with radius 'radius',
2355/// color 'rgba'
2356
2357void TGLUtil::DrawSphere(const TGLVertex3 & position, Double_t radius,
2358 const UChar_t rgba[4])
2359{
2360 static TGLQuadric quad;
2361 SetDrawColors(rgba);
2362 glPushMatrix();
2363 glTranslated(position.X(), position.Y(), position.Z());
2364 gluSphere(quad.Get(), radius, fgDrawQuality, fgDrawQuality);
2365 glPopMatrix();
2366}
2367
2368////////////////////////////////////////////////////////////////////////////////
2369/// Draw thick line (tube) defined by 'line', with head at end shape
2370/// 'head' - box/arrow/none, (head) size 'size', color 'rgba'
2371
2373 const UChar_t rgba[4])
2374{
2375 DrawLine(line.Start(), line.Vector(), head, size, rgba);
2376}
2377
2378////////////////////////////////////////////////////////////////////////////////
2379/// Draw thick line (tube) running from 'start', length 'vector',
2380/// with head at end of shape 'head' - box/arrow/none,
2381/// (head) size 'size', color 'rgba'
2382
2383void TGLUtil::DrawLine(const TGLVertex3 & start, const TGLVector3 & vector,
2384 ELineHeadShape head, Double_t size, const UChar_t rgba[4])
2385{
2386 static TGLQuadric quad;
2387
2388 // Draw 3D line (tube) with optional head shape
2389 SetDrawColors(rgba);
2390 glPushMatrix();
2391 TGLMatrix local(start, vector);
2392 glMultMatrixd(local.CArr());
2393
2394 Double_t headHeight=0;
2395 if (head == kLineHeadNone) {
2396 headHeight = 0.0;
2397 } else if (head == kLineHeadArrow) {
2398 headHeight = size*2.0;
2399 } else if (head == kLineHeadBox) {
2400 headHeight = size*1.4;
2401 }
2402
2403 // Line (tube) component
2404 gluCylinder(quad.Get(), 0.25*size, 0.25*size, vector.Mag() - headHeight, fgDrawQuality, 1);
2405 gluQuadricOrientation(quad.Get(), (GLenum)GLU_INSIDE);
2406 gluDisk(quad.Get(), 0.0, 0.25*size, fgDrawQuality, 1);
2407
2408 glTranslated(0.0, 0.0, vector.Mag() - headHeight); // Shift down local Z to end of line
2409
2410 if (head == kLineHeadNone) {
2411 // Cap end of line
2412 gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
2413 gluDisk(quad.Get(), 0.0, size/4.0, fgDrawQuality, 1);
2414 }
2415 else if (head == kLineHeadArrow) {
2416 // Arrow base / end line cap
2417 gluDisk(quad.Get(), 0.0, size, fgDrawQuality, 1);
2418 // Arrow cone
2419 gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
2420 gluCylinder(quad.Get(), size, 0.0, headHeight, fgDrawQuality, 1);
2421 } else if (head == kLineHeadBox) {
2422 // Box
2423 // TODO: Drawing box should be simpler - maybe make
2424 // a static helper which BB + others use.
2425 // Single face tesselation - ugly lighting
2426 gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
2427 TGLBoundingBox box(TGLVertex3(-size*.7, -size*.7, 0.0),
2428 TGLVertex3(size*.7, size*.7, headHeight));
2429 box.Draw(kTRUE);
2430 }
2431 glPopMatrix();
2432}
2433
2434////////////////////////////////////////////////////////////////////////////////
2435/// Draw ring, centered on 'center', lying on plane defined by 'center' & 'normal'
2436/// of outer radius 'radius', color 'rgba'
2437
2438void TGLUtil::DrawRing(const TGLVertex3 & center, const TGLVector3 & normal,
2439 Double_t radius, const UChar_t rgba[4])
2440{
2441 static TGLQuadric quad;
2442
2443 // Draw a ring, round vertex 'center', lying on plane defined by 'normal' vector
2444 // Radius defines the outer radius
2446
2447 Double_t outer = radius;
2448 Double_t width = radius*0.05;
2449 Double_t inner = outer - width;
2450
2451 // Shift into local system, looking down 'normal' vector, origin at center
2452 glPushMatrix();
2453 TGLMatrix local(center, normal);
2454 glMultMatrixd(local.CArr());
2455
2456 // Shift half width so rings centered over center vertex
2457 glTranslated(0.0, 0.0, -width/2.0);
2458
2459 // Inner and outer faces
2460 gluCylinder(quad.Get(), inner, inner, width, fgDrawQuality, 1);
2461 gluCylinder(quad.Get(), outer, outer, width, fgDrawQuality, 1);
2462
2463 // Top/bottom
2464 gluQuadricOrientation(quad.Get(), (GLenum)GLU_INSIDE);
2465 gluDisk(quad.Get(), inner, outer, fgDrawQuality, 1);
2466 glTranslated(0.0, 0.0, width);
2467 gluQuadricOrientation(quad.Get(), (GLenum)GLU_OUTSIDE);
2468 gluDisk(quad.Get(), inner, outer, fgDrawQuality, 1);
2469
2470 glPopMatrix();
2471}
2472
2473/**************************************************************************/
2474
2475////////////////////////////////////////////////////////////////////////////////
2476/// Draw a sphere- marker on world-coordinate 'pos' with pixel
2477/// radius 'radius'. Color argument is optional.
2478
2480 const TGLVertex3 & pos,
2481 Float_t radius,
2482 const UChar_t * rgba)
2483{
2484 static const UChar_t defColor[4] = { 250, 110, 0, 255 }; // Orange
2485
2486 radius = camera.ViewportDeltaToWorld(pos, radius, radius).Mag();
2487 DrawSphere(pos, radius, rgba ? rgba : defColor);
2488
2489}
2490
2491////////////////////////////////////////////////////////////////////////////////
2492/// Draw simple xyz-axes for given bounding-box.
2493
2495 const TGLBoundingBox & bbox,
2496 Int_t axesType,
2497 Float_t labelScale)
2498{
2499 if (axesType == kAxesNone)
2500 return;
2501
2502 static const UChar_t axesColors[][4] = {
2503 {128, 0, 0, 255}, // -ive X axis light red
2504 {255, 0, 0, 255}, // +ive X axis deep red
2505 { 0, 128, 0, 255}, // -ive Y axis light green
2506 { 0, 255, 0, 255}, // +ive Y axis deep green
2507 { 0, 0, 128, 255}, // -ive Z axis light blue
2508 { 0, 0, 255, 255} // +ive Z axis deep blue
2509 };
2510
2511 static const UChar_t xyz[][8] = {
2512 {0x44, 0x44, 0x28, 0x10, 0x10, 0x28, 0x44, 0x44},
2513 {0x10, 0x10, 0x10, 0x10, 0x10, 0x28, 0x44, 0x44},
2514 {0x7c, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x7c}
2515 };
2516
2517 // Axes draw at fixed screen size - back project to world
2518 TGLVector3 pixelVector = camera.ViewportDeltaToWorld(bbox.Center(), 1, 1);
2519 Double_t pixelSize = pixelVector.Mag();
2520
2521 // Find x/y/z min/max values
2522 TGLBoundingBox bb(bbox);
2524 Double_t min[3] = { bb.XMin(), bb.YMin(), bb.ZMin() };
2525 Double_t max[3] = { bb.XMax(), bb.YMax(), bb.ZMax() };
2526
2527 for (UInt_t i = 0; i < 3; i++) {
2528 TGLVertex3 start;
2529 TGLVector3 vector;
2530
2531 if (axesType == kAxesOrigin) {
2532 // Through origin axes
2533 start[(i+1)%3] = 0.0;
2534 start[(i+2)%3] = 0.0;
2535 } else {
2536 // Side axes
2537 start[(i+1)%3] = min[(i+1)%3];
2538 start[(i+2)%3] = min[(i+2)%3];
2539 }
2540 vector[(i+1)%3] = 0.0;
2541 vector[(i+2)%3] = 0.0;
2542
2543 // -ive axis?
2544 if (min[i] < 0.0) {
2545 // Runs from origin?
2546 if (max[i] > 0.0) {
2547 start[i] = 0.0;
2548 vector[i] = min[i];
2549 } else {
2550 start[i] = max[i];
2551 vector[i] = min[i] - max[i];
2552 }
2553 DrawLine(start, vector, kLineHeadNone, pixelSize*fgSimpleAxisWidthScale*2.5, axesColors[i*2]);
2554 }
2555 // +ive axis?
2556 if (max[i] > 0.0) {
2557 // Runs from origin?
2558 if (min[i] < 0.0) {
2559 start[i] = 0.0;
2560 vector[i] = max[i];
2561 } else {
2562 start[i] = min[i];
2563 vector[i] = max[i] - min[i];
2564 }
2565 DrawLine(start, vector, kLineHeadNone, pixelSize*fgSimpleAxisWidthScale*2.5, axesColors[i*2 + 1]);
2566 }
2567 }
2568
2569 // Draw origin sphere(s)
2570 if (axesType == kAxesOrigin) {
2571 // Single white origin sphere at 0, 0, 0
2572 DrawSphere(TGLVertex3(0.0, 0.0, 0.0), pixelSize*2.0, fgWhite);
2573 } else {
2574 for (UInt_t j = 0; j < 3; j++) {
2575 if (min[j] <= 0.0 && max[j] >= 0.0) {
2576 TGLVertex3 zero;
2577 zero[j] = 0.0;
2578 zero[(j+1)%3] = min[(j+1)%3];
2579 zero[(j+2)%3] = min[(j+2)%3];
2580 DrawSphere(zero, pixelSize*2.0, axesColors[j*2 + 1]);
2581 }
2582 }
2583 }
2584
2585 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2586
2587 // Labels
2588 Double_t padPixels = 25.0;
2589
2590 glDisable(GL_LIGHTING);
2591 for (UInt_t k = 0; k < 3; k++) {
2592 SetDrawColors(axesColors[k*2+1]);
2593 TGLVertex3 minPos, maxPos;
2594 if (axesType == kAxesOrigin) {
2595 minPos[(k+1)%3] = 0.0;
2596 minPos[(k+2)%3] = 0.0;
2597 } else {
2598 minPos[(k+1)%3] = min[(k+1)%3];
2599 minPos[(k+2)%3] = min[(k+2)%3];
2600 }
2601 maxPos = minPos;
2602 minPos[k] = min[k];
2603 maxPos[k] = max[k];
2604
2605 TGLVector3 axis = maxPos - minPos;
2606 TGLVector3 axisViewport = camera.WorldDeltaToViewport(minPos, axis);
2607
2608 // Skip drawing if viewport projection of axis very small - labels will overlap
2609 // Occurs with orthographic cameras
2610 if (axisViewport.Mag() < 1) {
2611 continue;
2612 }
2613
2614 minPos -= camera.ViewportDeltaToWorld(minPos, padPixels*axisViewport.X()/axisViewport.Mag(),
2615 padPixels*axisViewport.Y()/axisViewport.Mag());
2616 axisViewport = camera.WorldDeltaToViewport(maxPos, -axis);
2617 maxPos -= camera.ViewportDeltaToWorld(maxPos, padPixels*axisViewport.X()/axisViewport.Mag(),
2618 padPixels*axisViewport.Y()/axisViewport.Mag());
2619
2620 DrawNumber(Form("%.0f", labelScale * min[k]), minPos, kTRUE); // Min value
2621 DrawNumber(Form("%.0f", labelScale * max[k]), maxPos, kTRUE); // Max value
2622
2623 // Axis name beside max value
2624 TGLVertex3 namePos = maxPos -
2625 camera.ViewportDeltaToWorld(maxPos, padPixels*axisViewport.X()/axisViewport.Mag(),
2626 padPixels*axisViewport.Y()/axisViewport.Mag());
2627 glRasterPos3dv(namePos.CArr());
2628 glBitmap(8, 8, 0.0, 4.0, 0.0, 0.0, xyz[k]); // Axis Name
2629 }
2630}
2631
2632////////////////////////////////////////////////////////////////////////////////
2633/// Draw number in string 'num' via internal 8x8-pixel bitmap on
2634/// vertex 'pos'. If 'center' is true, the number is centered on 'pos'.
2635/// Only numbers, '.', '-' and ' ' are supported.
2636
2638 const TGLVertex3 & pos,
2639 Bool_t center)
2640{
2641 static const UChar_t digits[][8] = {
2642 {0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38},//0
2643 {0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x10, 0x10},//1
2644 {0x7c, 0x44, 0x20, 0x18, 0x04, 0x04, 0x44, 0x38},//2
2645 {0x38, 0x44, 0x04, 0x04, 0x18, 0x04, 0x44, 0x38},//3
2646 {0x04, 0x04, 0x04, 0x04, 0x7c, 0x44, 0x44, 0x44},//4
2647 {0x7c, 0x44, 0x04, 0x04, 0x7c, 0x40, 0x40, 0x7c},//5
2648 {0x7c, 0x44, 0x44, 0x44, 0x7c, 0x40, 0x40, 0x7c},//6
2649 {0x20, 0x20, 0x20, 0x10, 0x08, 0x04, 0x44, 0x7c},//7
2650 {0x38, 0x44, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38},//8
2651 {0x7c, 0x44, 0x04, 0x04, 0x7c, 0x44, 0x44, 0x7c},//9
2652 {0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},//.
2653 {0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00},//-
2654 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} //space
2655 };
2656
2657 Double_t xOffset = 0, yOffset = 0;
2658 if (center)
2659 {
2660 xOffset = 3.5 * num.Length();
2661 yOffset = 4.0;
2662 }
2663
2664 glRasterPos3dv(pos.CArr());
2665 for (Ssiz_t i = 0, e = num.Length(); i < e; ++i) {
2666 if (num[i] == '.') {
2667 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[10]);
2668 } else if (num[i] == '-') {
2669 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[11]);
2670 } else if (num[i] == ' ') {
2671 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[12]);
2672 } else if (num[i] >= '0' && num[i] <= '9') {
2673 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[num[i] - '0']);
2674 }
2675 }
2676}
2677
2678
2679/**************************************************************************/
2680/**************************************************************************/
2681
2682////////////////////////////////////////////////////////////////////////////////
2683/// Constructor - change state only if necessary.
2684
2686 fWhat(what)
2687{
2688 fState = glIsEnabled(fWhat);
2689 fFlip = (fState != state);
2690 if (fFlip)
2691 SetState(state);
2692}
2693
2694////////////////////////////////////////////////////////////////////////////////
2695/// Destructor - reset state if changed.
2696
2698{
2699 if (fFlip)
2701}
2702
2703////////////////////////////////////////////////////////////////////////////////
2704
2706{
2707 if (s)
2708 glEnable(fWhat);
2709 else
2710 glDisable(fWhat);
2711}
2712
2713
2714////////////////////////////////////////////////////////////////////////////////
2715/// Constructor - change state only if necessary.
2716
2718 fWhat(what)
2719{
2720 fFlip = ! glIsEnabled(fWhat) && state;
2721 if (fFlip)
2722 glEnable(fWhat);
2723}
2724
2725////////////////////////////////////////////////////////////////////////////////
2726/// Destructor - reset state if changed.
2727
2729{
2730 if (fFlip)
2731 glDisable(fWhat);
2732}
2733
2734
2735////////////////////////////////////////////////////////////////////////////////
2736
2738 fWhat(what), fState(0), fFlip(kFALSE), fFoo(foo)
2739 {
2740 glGetFloatv(fWhat, &fState);
2741 fFlip = (fState != state);
2742 if (fFlip) fFoo(state);
2743 }
2744
2745////////////////////////////////////////////////////////////////////////////////
2746
2748 {
2749 if (fFlip) fFoo(fState);
2750 }
2751
2752
2753////////////////////////////////////////////////////////////////////////////////
2754/// TGLEnableGuard constructor.
2755
2757 : fCap(cap)
2758{
2759 glEnable(GLenum(fCap));
2760}
2761
2762////////////////////////////////////////////////////////////////////////////////
2763/// TGLEnableGuard destructor.
2764
2766{
2767 glDisable(GLenum(fCap));
2768}
2769
2770////////////////////////////////////////////////////////////////////////////////
2771/// TGLDisableGuard constructor.
2772
2774 : fCap(cap)
2775{
2776 glDisable(GLenum(fCap));
2777}
2778
2779////////////////////////////////////////////////////////////////////////////////
2780/// TGLDisableGuard destructor.
2781
2783{
2784 glEnable(GLenum(fCap));
2785}
2786
2787/** \class TGLSelectionBuffer
2788\ingroup opengl
2789*/
2790
2792
2793////////////////////////////////////////////////////////////////////////////////
2794/// TGLSelectionBuffer constructor.
2795
2797 : fWidth(0), fHeight(0)
2798{
2799}
2800
2801////////////////////////////////////////////////////////////////////////////////
2802/// TGLSelectionBuffer destructor.
2803
2805{
2806}
2807
2808////////////////////////////////////////////////////////////////////////////////
2809/// Read color buffer.
2810
2812{
2813 fWidth = w;
2814 fHeight = h;
2815 fBuffer.resize(w * h * 4);
2816 glPixelStorei(GL_PACK_ALIGNMENT, 1);
2817 glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, &fBuffer[0]);
2818}
2819
2820////////////////////////////////////////////////////////////////////////////////
2821/// Read color buffer.
2822
2824{
2825 fWidth = w;
2826 fHeight = h;
2827 fBuffer.resize(w * h * 4);
2828 glPixelStorei(GL_PACK_ALIGNMENT, 1);
2829 glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, &fBuffer[0]);
2830}
2831
2832////////////////////////////////////////////////////////////////////////////////
2833/// Get pixel color.
2834
2836{
2837 if (px < 0)
2838 px = 0;
2839 if (py < 0)
2840 py = 0;
2841
2842 if (UInt_t(px * fWidth * 4 + py * 4) > fBuffer.size())
2843 return &fBuffer[0];
2844
2845 return &fBuffer[px * fWidth * 4 + py * 4];
2846}
2847
2848namespace Rgl {
2849
2850const Float_t gRedEmission[] = {1.f, 0.f, 0.f, 1.f};
2851const Float_t gGreenEmission[] = {0.f, 1.f, 0.f, 1.f};
2852const Float_t gBlueEmission[] = {0.f, 0.f, 1.f, 1.f};
2853const Float_t gOrangeEmission[] = {1.f, 0.4f, 0.f, 1.f};
2854const Float_t gWhiteEmission[] = {1.f, 1.f, 1.f, 1.f};
2855const Float_t gGrayEmission[] = {0.3f,0.3f, 0.3f,1.f};
2856const Float_t gNullEmission[] = {0.f, 0.f, 0.f, 1.f};
2857
2858namespace {
2859 struct RGB_t {
2860 Int_t fRGB[3];
2861 };
2862
2863 RGB_t gColorTriplets[] = {{{255, 0, 0}},
2864 {{0, 255, 0}},
2865 {{0, 0, 255}},
2866 {{255, 255, 0}},
2867 {{255, 0, 255}},
2868 {{0, 255, 255}},
2869 {{255, 255, 255}}};
2870
2871 Bool_t operator < (const RGB_t &lhs, const RGB_t &rhs)
2872 {
2873 if (lhs.fRGB[0] < rhs.fRGB[0])
2874 return kTRUE;
2875 else if (lhs.fRGB[0] > rhs.fRGB[0])
2876 return kFALSE;
2877 else if (lhs.fRGB[1] < rhs.fRGB[1])
2878 return kTRUE;
2879 else if (lhs.fRGB[1] > rhs.fRGB[1])
2880 return kFALSE;
2881 else if (lhs.fRGB[2] < rhs.fRGB[2])
2882 return kTRUE;
2883
2884 return kFALSE;
2885 }
2886
2887 typedef std::map<Int_t, RGB_t> ColorLookupTable_t;
2888 typedef ColorLookupTable_t::const_iterator CLTCI_t;
2889
2890 ColorLookupTable_t gObjectIDToColor;
2891
2892 typedef std::map<RGB_t, Int_t> ObjectLookupTable_t;
2893 typedef ObjectLookupTable_t::const_iterator OLTCI_t;
2894
2895 ObjectLookupTable_t gColorToObjectID;
2896}
2897////////////////////////////////////////////////////////////////////////////////
2898///Object id encoded as rgb triplet.
2899
2900void ObjectIDToColor(Int_t objectID, Bool_t highColor)
2901{
2902 if (!highColor)
2903 glColor3ub(objectID & 0xff, (objectID & 0xff00) >> 8, (objectID & 0xff0000) >> 16);
2904 else {
2905 if (!gObjectIDToColor.size()) {
2906 //Initialize lookup tables.
2907 for (Int_t i = 0, id = 1; i < Int_t(sizeof gColorTriplets / sizeof(RGB_t)); ++i, ++id)
2908 gObjectIDToColor[id] = gColorTriplets[i];
2909 for (Int_t i = 0, id = 1; i < Int_t(sizeof gColorTriplets / sizeof(RGB_t)); ++i, ++id)
2910 gColorToObjectID[gColorTriplets[i]] = id;
2911 }
2912
2913 CLTCI_t it = gObjectIDToColor.find(objectID);
2914
2915 if (it != gObjectIDToColor.end())
2916 glColor3ub(it->second.fRGB[0], it->second.fRGB[1], it->second.fRGB[2]);
2917 else {
2918 Error("ObjectIDToColor", "No color for such object ID: %d", objectID);
2919 glColor3ub(0, 0, 0);
2920 }
2921 }
2922}
2923
2924////////////////////////////////////////////////////////////////////////////////
2925
2927{
2928 if (!highColor)
2929 return pixel[0] | (pixel[1] << 8) | (pixel[2] << 16);
2930 else {
2931 if (!gObjectIDToColor.size())
2932 return 0;
2933
2934 RGB_t triplet = {{pixel[0], pixel[1], pixel[2]}};
2935 OLTCI_t it = gColorToObjectID.find(triplet);
2936
2937 if (it != gColorToObjectID.end())
2938 return it->second;
2939 else
2940 return 0;
2941 }
2942}
2943
2944
2945////////////////////////////////////////////////////////////////////////////////
2946///Draw quad outline.
2947
2949 const TGLVertex3 &v3, const TGLVertex3 &v4)
2950{
2951 glBegin(GL_LINE_LOOP);
2952 glVertex3dv(v1.CArr());
2953 glVertex3dv(v2.CArr());
2954 glVertex3dv(v3.CArr());
2955 glVertex3dv(v4.CArr());
2956 glEnd();
2957}
2958
2959////////////////////////////////////////////////////////////////////////////////
2960///Draw quad face.
2961
2963 const TGLVertex3 &v3, const TGLVector3 &normal)
2964{
2965 glBegin(GL_POLYGON);
2966 glNormal3dv(normal.CArr());
2967 glVertex3dv(v0.CArr());
2968 glVertex3dv(v1.CArr());
2969 glVertex3dv(v2.CArr());
2970 glVertex3dv(v3.CArr());
2971 glEnd();
2972}
2973
2974////////////////////////////////////////////////////////////////////////////////
2975///Draw quad face.
2976
2977void DrawQuadFilled(const Double_t *v0, const Double_t *v1, const Double_t *v2, const Double_t *v3,
2978 const Double_t *normal)
2979{
2980 glBegin(GL_QUADS);
2981 glNormal3dv(normal);
2982 glVertex3dv(v0);
2983 glVertex3dv(v1);
2984 glVertex3dv(v2);
2985 glVertex3dv(v3);
2986 glEnd();
2987}
2988
2989////////////////////////////////////////////////////////////////////////////////
2990///Draws triangle face, each vertex has its own averaged normal
2991
2993 const TGLVector3 &norm1, const TGLVector3 &norm2, const TGLVector3 &norm3)
2994{
2995 glBegin(GL_POLYGON);
2996 glNormal3dv(norm1.CArr());
2997 glVertex3dv(v1.CArr());
2998 glNormal3dv(norm2.CArr());
2999 glVertex3dv(v2.CArr());
3000 glNormal3dv(norm3.CArr());
3001 glVertex3dv(v3.CArr());
3002 glEnd();
3003}
3004
3005const Int_t gBoxFrontQuads[][4] = {{0, 1, 2, 3}, {4, 0, 3, 5}, {4, 5, 6, 7}, {7, 6, 2, 1}};
3006const Double_t gBoxFrontNormals[][3] = {{-1., 0., 0.}, {0., -1., 0.}, {1., 0., 0.}, {0., 1., 0.}};
3007const Int_t gBoxFrontPlanes[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 0}};
3008
3009const Int_t gBoxBackQuads[][4] = {{7, 1, 2, 6}, {4, 7, 6, 5}, {0, 4, 5, 3}, {0, 3, 2, 1}};
3010const Double_t gBoxBackNormals[][3] = {{0., -1., 0.}, {-1., 0., 0.}, {0., 1., 0.}, {1., 0., 0.}};
3011const Int_t gBoxBackPlanes[][2] = {{0, 1}, {3, 0}, {2, 3}, {1, 2}};
3012
3013////////////////////////////////////////////////////////////////////////////////
3014///Draws lego's bar as a 3d box
3015
3016void DrawBoxFront(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax,
3017 Double_t zMin, Double_t zMax, Int_t fp)
3018{
3019 if (zMax < zMin)
3020 std::swap(zMax, zMin);
3021
3022 //Bottom is always drawn.
3023 glBegin(GL_POLYGON);
3024 glNormal3d(0., 0., -1.);
3025 glVertex3d(xMax, yMin, zMin);
3026 glVertex3d(xMin, yMin, zMin);
3027 glVertex3d(xMin, yMax, zMin);
3028 glVertex3d(xMax, yMax, zMin);
3029 glEnd();
3030 //Draw two visible front planes.
3031 const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
3032 {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
3033 const Int_t *verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
3034
3035 glBegin(GL_POLYGON);
3036 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][0]]);
3037 glVertex3dv(box[verts[0]]);
3038 glVertex3dv(box[verts[1]]);
3039 glVertex3dv(box[verts[2]]);
3040 glVertex3dv(box[verts[3]]);
3041 glEnd();
3042
3043 verts = gBoxFrontQuads[gBoxFrontPlanes[fp][1]];
3044
3045 glBegin(GL_POLYGON);
3046 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][1]]);
3047 glVertex3dv(box[verts[0]]);
3048 glVertex3dv(box[verts[1]]);
3049 glVertex3dv(box[verts[2]]);
3050 glVertex3dv(box[verts[3]]);
3051 glEnd();
3052
3053 //Top is always drawn.
3054 glBegin(GL_POLYGON);
3055 glNormal3d(0., 0., 1.);
3056 glVertex3d(xMax, yMin, zMax);
3057 glVertex3d(xMax, yMax, zMax);
3058 glVertex3d(xMin, yMax, zMax);
3059 glVertex3d(xMin, yMin, zMax);
3060 glEnd();
3061}
3062
3063////////////////////////////////////////////////////////////////////////////////
3064///Draws lego's bar as a 3d box
3065
3067 Double_t zMin, Double_t zMax, Int_t fp)
3068{
3069 if (zMax < zMin)
3070 std::swap(zMax, zMin);
3071
3072 //The order is: 1) two back planes, 2) bottom plane, 3) two front planes,
3073 //4) top.
3074
3075 //Bottom is always drawn.
3076 glBegin(GL_POLYGON);
3077 glNormal3d(0., 0., -1.);
3078 glVertex3d(xMax, yMin, zMin);
3079 glVertex3d(xMin, yMin, zMin);
3080 glVertex3d(xMin, yMax, zMin);
3081 glVertex3d(xMax, yMax, zMin);
3082 glEnd();
3083
3084 const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
3085 {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
3086
3087 //Draw two back planes.
3088 const Int_t *verts = gBoxBackQuads[gBoxBackPlanes[fp][0]];
3089
3090 glBegin(GL_POLYGON);
3091 glNormal3dv(gBoxBackNormals[gBoxBackPlanes[fp][0]]);
3092 glVertex3dv(box[verts[0]]);
3093 glVertex3dv(box[verts[1]]);
3094 glVertex3dv(box[verts[2]]);
3095 glVertex3dv(box[verts[3]]);
3096 glEnd();
3097
3098 verts = gBoxBackQuads[gBoxBackPlanes[fp][1]];
3099
3100 glBegin(GL_POLYGON);
3101 glNormal3dv(gBoxBackNormals[gBoxBackPlanes[fp][1]]);
3102 glVertex3dv(box[verts[0]]);
3103 glVertex3dv(box[verts[1]]);
3104 glVertex3dv(box[verts[2]]);
3105 glVertex3dv(box[verts[3]]);
3106 glEnd();
3107
3108 //Draw two visible front planes.
3109 verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
3110
3111 glBegin(GL_POLYGON);
3112 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][0]]);
3113 glVertex3dv(box[verts[0]]);
3114 glVertex3dv(box[verts[1]]);
3115 glVertex3dv(box[verts[2]]);
3116 glVertex3dv(box[verts[3]]);
3117 glEnd();
3118
3119 verts = gBoxFrontQuads[gBoxFrontPlanes[fp][1]];
3120
3121 glBegin(GL_POLYGON);
3122 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][1]]);
3123 glVertex3dv(box[verts[0]]);
3124 glVertex3dv(box[verts[1]]);
3125 glVertex3dv(box[verts[2]]);
3126 glVertex3dv(box[verts[3]]);
3127 glEnd();
3128
3129 //Top is always drawn.
3130 glBegin(GL_POLYGON);
3131 glNormal3d(0., 0., 1.);
3132 glVertex3d(xMax, yMin, zMax);
3133 glVertex3d(xMax, yMax, zMax);
3134 glVertex3d(xMin, yMax, zMax);
3135 glVertex3d(xMin, yMin, zMax);
3136 glEnd();
3137}
3138
3139////////////////////////////////////////////////////////////////////////////////
3140///Draws lego's bar as a 3d box
3141///LULULULU
3142
3144 Double_t yMax, Double_t zMin, Double_t zMax,
3145 Double_t texMin, Double_t texMax, Int_t fp)
3146{
3147 if (zMax < zMin) {
3148 std::swap(zMax, zMin);
3149 std::swap(texMax, texMin);
3150 }
3151
3152 //Top and bottom are always drawn.
3153 glBegin(GL_POLYGON);
3154 glNormal3d(0., 0., 1.);
3155 glTexCoord1d(texMax);
3156 glVertex3d(xMax, yMin, zMax);
3157 glVertex3d(xMax, yMax, zMax);
3158 glVertex3d(xMin, yMax, zMax);
3159 glVertex3d(xMin, yMin, zMax);
3160 glEnd();
3161
3162 glBegin(GL_POLYGON);
3163 glTexCoord1d(texMin);
3164 glNormal3d(0., 0., -1.);
3165 glVertex3d(xMax, yMin, zMin);
3166 glVertex3d(xMin, yMin, zMin);
3167 glVertex3d(xMin, yMax, zMin);
3168 glVertex3d(xMax, yMax, zMin);
3169 glEnd();
3170 //Draw two visible front planes.
3171 const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
3172 {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
3173
3174 const Double_t tex[] = {texMax, texMax, texMin, texMin, texMax, texMin, texMin, texMax};
3175 const Int_t *verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
3176
3177 glBegin(GL_POLYGON);
3178 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][0]]);
3179 glTexCoord1d(tex[verts[0]]);
3180 glVertex3dv(box[verts[0]]);
3181 glTexCoord1d(tex[verts[1]]);
3182 glVertex3dv(box[verts[1]]);
3183 glTexCoord1d(tex[verts[2]]);
3184 glVertex3dv(box[verts[2]]);
3185 glTexCoord1d(tex[verts[3]]);
3186 glVertex3dv(box[verts[3]]);
3187 glEnd();
3188
3189 verts = gBoxFrontQuads[gBoxFrontPlanes[fp][1]];
3190
3191 glBegin(GL_POLYGON);
3192 glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][1]]);
3193 glTexCoord1d(tex[verts[0]]);
3194 glVertex3dv(box[verts[0]]);
3195 glTexCoord1d(tex[verts[1]]);
3196 glVertex3dv(box[verts[1]]);
3197 glTexCoord1d(tex[verts[2]]);
3198 glVertex3dv(box[verts[2]]);
3199 glTexCoord1d(tex[verts[3]]);
3200 glVertex3dv(box[verts[3]]);
3201 glEnd();
3202}
3203
3204////////////////////////////////////////////////////////////////////////////////
3205
3207 const Double_t *rgba1, const Double_t *rgba2)
3208{
3209 assert(rgba1 != 0 && "DrawBoxWithGradientFill, parameter 'rgba1' is null");
3210 assert(rgba2 != 0 && "DrawBoxWithGradientFill, parameter 'rgba2' is null");
3211
3212 glBegin(GL_POLYGON);
3213 glColor4dv(rgba1);
3214 glVertex2d(x1, y1);
3215 glVertex2d(x2, y1);
3216 glColor4dv(rgba2);
3217 glVertex2d(x2, y2);
3218 glVertex2d(x1, y2);
3219 glEnd();
3220}
3221
3222////////////////////////////////////////////////////////////////////////////////
3223///TODO: is it possible to use GLdouble to avoid problems with Double_t/GLdouble if they
3224///are not the same type?
3225
3226void DrawQuadStripWithRadialGradientFill(unsigned nPoints, const Double_t *inner, const Double_t *innerRGBA,
3227 const Double_t *outer, const Double_t *outerRGBA)
3228{
3229 assert(nPoints != 0 &&
3230 "DrawQuadStripWithRadialGradientFill, invalid number of points");
3231 assert(inner != 0 &&
3232 "DrawQuadStripWithRadialGradientFill, parameter 'inner' is null");
3233 assert(innerRGBA != 0 &&
3234 "DrawQuadStripWithRadialGradientFill, parameter 'innerRGBA' is null");
3235 assert(outer != 0 &&
3236 "DrawQuadStripWithRadialGradientFill, parameter 'outer' is null");
3237 assert(outerRGBA != 0 &&
3238 "DrawQuadStripWithRadialGradientFill, parameter 'outerRGBA' is null");
3239
3240 glBegin(GL_QUAD_STRIP);
3241 for (UInt_t j = 0; j < nPoints; ++j) {
3242 glColor4dv(innerRGBA);
3243 glVertex2dv(inner + j * 2);
3244 glColor4dv(outerRGBA);
3245 glVertex2dv(outer + j * 2);
3246 }
3247 glEnd();
3248}
3249
3250////////////////////////////////////////////////////////////////////////////////
3251///Cylinder for lego3.
3252
3253void DrawCylinder(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin,
3254 Double_t yMax, Double_t zMin, Double_t zMax)
3255{
3256 GLUquadric *quad = quadric->Get();
3257
3258 if (quad) {
3259 if (zMin > zMax)
3260 std::swap(zMin, zMax);
3261 const Double_t xCenter = xMin + (xMax - xMin) / 2;
3262 const Double_t yCenter = yMin + (yMax - yMin) / 2;
3263 const Double_t radius = TMath::Min((xMax - xMin) / 2, (yMax - yMin) / 2);
3264
3265 glPushMatrix();
3266 glTranslated(xCenter, yCenter, zMin);
3267 gluCylinder(quad, radius, radius, zMax - zMin, 40, 1);
3268 glPopMatrix();
3269 glPushMatrix();
3270 glTranslated(xCenter, yCenter, zMax);
3271 gluDisk(quad, 0., radius, 40, 1);
3272 glPopMatrix();
3273 glPushMatrix();
3274 glTranslated(xCenter, yCenter, zMin);
3275 glRotated(180., 0., 1., 0.);
3276 gluDisk(quad, 0., radius, 40, 1);
3277 glPopMatrix();
3278 }
3279}
3280
3281////////////////////////////////////////////////////////////////////////////////
3282///Cylinder for lego3.
3283
3284void DrawSphere(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin,
3285 Double_t yMax, Double_t zMin, Double_t zMax)
3286{
3287 GLUquadric *quad = quadric->Get();
3288
3289 if (quad) {
3290 const Double_t xCenter = xMin + (xMax - xMin) / 2;
3291 const Double_t yCenter = yMin + (yMax - yMin) / 2;
3292 const Double_t zCenter = zMin + (zMax - zMin) / 2;
3293
3294 const Double_t radius = TMath::Min((zMax - zMin) / 2,
3295 TMath::Min((xMax - xMin) / 2, (yMax - yMin) / 2));
3296
3297 glPushMatrix();
3298 glTranslated(xCenter, yCenter, zCenter);
3299 gluSphere(quad, radius, 10, 10);
3300 glPopMatrix();
3301 }
3302}
3303
3304
3305////////////////////////////////////////////////////////////////////////////////
3306
3307void DrawError(Double_t xMin, Double_t xMax, Double_t yMin,
3308 Double_t yMax, Double_t zMin, Double_t zMax)
3309{
3310 const Double_t xWid = xMax - xMin;
3311 const Double_t yWid = yMax - yMin;
3312
3313 glBegin(GL_LINES);
3314 glVertex3d(xMin + xWid / 2, yMin + yWid / 2, zMin);
3315 glVertex3d(xMin + xWid / 2, yMin + yWid / 2, zMax);
3316 glEnd();
3317
3318 glBegin(GL_LINES);
3319 glVertex3d(xMin + xWid / 2, yMin, zMin);
3320 glVertex3d(xMin + xWid / 2, yMax, zMin);
3321 glEnd();
3322
3323 glBegin(GL_LINES);
3324 glVertex3d(xMin, yMin + yWid / 2, zMin);
3325 glVertex3d(xMax, yMin + yWid / 2, zMin);
3326 glEnd();
3327}
3328
3330{
3331 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1]);
3332 if (n > 0.) {
3333 normal[0] = v[0] / n;
3334 normal[1] = v[1] / n;
3335 normal[2] = 0.;
3336 } else {
3337 normal[0] = v[0];
3338 normal[1] = v[1];
3339 normal[2] = 0.;
3340 }
3341}
3342
3344{
3345 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1]);
3346 if (n > 0.) {
3347 normal[0] = -v[0] / n;
3348 normal[1] = -v[1] / n;
3349 normal[2] = 0.;
3350 } else {
3351 normal[0] = -v[0];
3352 normal[1] = -v[1];
3353 normal[2] = 0.;
3354 }
3355}
3356
3357void DrawTrapezoid(const Double_t ver[][2], Double_t zMin, Double_t zMax, Bool_t color)
3358{
3359 //In polar coordinates, box became trapezoid.
3360 //Four faces need normal calculations.
3361 if (zMin > zMax)
3362 std::swap(zMin, zMax);
3363 //top
3364 glBegin(GL_POLYGON);
3365 glNormal3d(0., 0., 1.);
3366 glVertex3d(ver[0][0], ver[0][1], zMax);
3367 glVertex3d(ver[1][0], ver[1][1], zMax);
3368 glVertex3d(ver[2][0], ver[2][1], zMax);
3369 glVertex3d(ver[3][0], ver[3][1], zMax);
3370 glEnd();
3371 //bottom
3372 glBegin(GL_POLYGON);
3373 glNormal3d(0., 0., -1.);
3374 glVertex3d(ver[0][0], ver[0][1], zMin);
3375 glVertex3d(ver[3][0], ver[3][1], zMin);
3376 glVertex3d(ver[2][0], ver[2][1], zMin);
3377 glVertex3d(ver[1][0], ver[1][1], zMin);
3378 glEnd();
3379 //
3380
3381 Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
3382 {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
3383 {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
3384 {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
3385 Double_t normal[3] = {0.};
3386 glBegin(GL_POLYGON);
3387 CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glVertex3dv(trapezoid[1]);
3388 CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glVertex3dv(trapezoid[2]);
3389 CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glVertex3dv(trapezoid[6]);
3390 CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glVertex3dv(trapezoid[5]);
3391 glEnd();
3392
3393 glBegin(GL_POLYGON);
3394 CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glVertex3dv(trapezoid[0]);
3395 CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glVertex3dv(trapezoid[4]);
3396 CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glVertex3dv(trapezoid[7]);
3397 CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glVertex3dv(trapezoid[3]);
3398 glEnd();
3399
3400 glBegin(GL_POLYGON);
3401 if (color) {
3402 TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
3403 glNormal3dv(normal);
3404 }
3405 glVertex3dv(trapezoid[0]);
3406 glVertex3dv(trapezoid[1]);
3407 glVertex3dv(trapezoid[5]);
3408 glVertex3dv(trapezoid[4]);
3409 glEnd();
3410
3411 glBegin(GL_POLYGON);
3412 if (color) {
3413 TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
3414 glNormal3dv(normal);
3415 }
3416 glVertex3dv(trapezoid[3]);
3417 glVertex3dv(trapezoid[7]);
3418 glVertex3dv(trapezoid[6]);
3419 glVertex3dv(trapezoid[2]);
3420 glEnd();
3421}
3422
3423////////////////////////////////////////////////////////////////////////////////
3424///In polar coordinates, box became trapezoid.
3425///Four faces need normal calculations.
3426
3427void DrawTrapezoidTextured(const Double_t ver[][2], Double_t zMin, Double_t zMax,
3428 Double_t texMin, Double_t texMax)
3429{
3430 if (zMin > zMax) {
3431 std::swap(zMin, zMax);
3432 std::swap(texMin, texMax);
3433 }
3434
3435 //top
3436 glBegin(GL_POLYGON);
3437 glNormal3d(0., 0., 1.);
3438 glTexCoord1d(texMax);
3439 glVertex3d(ver[0][0], ver[0][1], zMax);
3440 glVertex3d(ver[1][0], ver[1][1], zMax);
3441 glVertex3d(ver[2][0], ver[2][1], zMax);
3442 glVertex3d(ver[3][0], ver[3][1], zMax);
3443 glEnd();
3444 //bottom
3445 glBegin(GL_POLYGON);
3446 glNormal3d(0., 0., -1.);
3447 glTexCoord1d(texMin);
3448 glVertex3d(ver[0][0], ver[0][1], zMin);
3449 glVertex3d(ver[3][0], ver[3][1], zMin);
3450 glVertex3d(ver[2][0], ver[2][1], zMin);
3451 glVertex3d(ver[1][0], ver[1][1], zMin);
3452 glEnd();
3453 //
3454
3455 Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
3456 {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
3457 {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
3458 {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
3459 Double_t normal[3] = {0.};
3460 glBegin(GL_POLYGON);
3461 CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[1]);
3462 CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[2]);
3463 CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[6]);
3464 CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[5]);
3465 glEnd();
3466
3467 glBegin(GL_POLYGON);
3468 CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[0]);
3469 CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[4]);
3470 CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[7]);
3471 CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[3]);
3472 glEnd();
3473
3474 glBegin(GL_POLYGON);
3475 TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
3476 glNormal3dv(normal);
3477 glTexCoord1d(texMin);
3478 glVertex3dv(trapezoid[0]);
3479 glTexCoord1d(texMin);
3480 glVertex3dv(trapezoid[1]);
3481 glTexCoord1d(texMax);
3482 glVertex3dv(trapezoid[5]);
3483 glTexCoord1d(texMax);
3484 glVertex3dv(trapezoid[4]);
3485 glEnd();
3486
3487 glBegin(GL_POLYGON);
3488 TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
3489 glNormal3dv(normal);
3490 glTexCoord1d(texMin);
3491 glVertex3dv(trapezoid[3]);
3492 glTexCoord1d(texMax);
3493 glVertex3dv(trapezoid[7]);
3494 glTexCoord1d(texMax);
3495 glVertex3dv(trapezoid[6]);
3496 glTexCoord1d(texMin);
3497 glVertex3dv(trapezoid[2]);
3498 glEnd();
3499}
3500
3501////////////////////////////////////////////////////////////////////////////////
3502///In polar coordinates, box became trapezoid.
3503
3504void DrawTrapezoidTextured2(const Double_t ver[][2], Double_t zMin, Double_t zMax,
3505 Double_t texMin, Double_t texMax)
3506{
3507 if (zMin > zMax)
3508 std::swap(zMin, zMax);
3509
3510 const Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
3511 {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
3512 {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
3513 {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
3514 const Double_t tex[] = {texMin, texMax, texMax, texMin, texMin, texMax, texMax, texMin};
3515 //top
3516 glBegin(GL_POLYGON);
3517 glNormal3d(0., 0., 1.);
3518 glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
3519 glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
3520 glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
3521 glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
3522 glEnd();
3523 //bottom
3524 glBegin(GL_POLYGON);
3525 glNormal3d(0., 0., -1.);
3526 glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
3527 glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
3528 glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
3529 glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
3530 glEnd();
3531 //
3532 glBegin(GL_POLYGON);
3533 Double_t normal[3] = {};
3534 CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
3535 CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
3536 CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
3537 CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
3538 glEnd();
3539
3540 glBegin(GL_POLYGON);
3541 CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
3542 CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
3543 CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
3544 CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
3545 glEnd();
3546
3547 glBegin(GL_POLYGON);
3548 TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
3549 glNormal3dv(normal);
3550 glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
3551 glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
3552 glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
3553 glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
3554 glEnd();
3555
3556 glBegin(GL_POLYGON);
3557 TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
3558 glNormal3dv(normal);
3559 glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
3560 glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
3561 glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
3562 glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
3563 glEnd();
3564}
3565
3566////////////////////////////////////////////////////////////////////////////////
3567
3568void SphericalNormal(const Double_t *v, Double_t *normal)
3569{
3570 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
3571 if (n > 0.) {
3572 normal[0] = v[0] / n;
3573 normal[1] = v[1] / n;
3574 normal[2] = v[2] / n;
3575 } else {
3576 normal[0] = v[0];
3577 normal[1] = v[1];
3578 normal[2] = v[2];
3579 }
3580}
3581
3582////////////////////////////////////////////////////////////////////////////////
3583
3585{
3586 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
3587 if (n > 0.) {
3588 normal[0] = -v[0] / n;
3589 normal[1] = -v[1] / n;
3590 normal[2] = -v[2] / n;
3591 } else {
3592 normal[0] = -v[0];
3593 normal[1] = -v[1];
3594 normal[2] = -v[2];
3595 }
3596}
3597
3598////////////////////////////////////////////////////////////////////////////////
3599
3600void DrawTrapezoid(const Double_t ver[][3])
3601{
3602 Double_t normal[3] = {0.};
3603
3604 glBegin(GL_POLYGON);
3605 TMath::Normal2Plane(ver[1], ver[2], ver[3], normal);
3606 glNormal3dv(normal);
3607 glVertex3dv(ver[0]);
3608 glVertex3dv(ver[1]);
3609 glVertex3dv(ver[2]);
3610 glVertex3dv(ver[3]);
3611 glEnd();
3612 //bottom
3613 glBegin(GL_POLYGON);
3614 TMath::Normal2Plane(ver[4], ver[7], ver[6], normal);
3615 glNormal3dv(normal);
3616 glVertex3dv(ver[4]);
3617 glVertex3dv(ver[7]);
3618 glVertex3dv(ver[6]);
3619 glVertex3dv(ver[5]);
3620 glEnd();
3621 //
3622
3623 glBegin(GL_POLYGON);
3624 TMath::Normal2Plane(ver[0], ver[3], ver[7], normal);
3625 glNormal3dv(normal);
3626 glVertex3dv(ver[0]);
3627 glVertex3dv(ver[3]);
3628 glVertex3dv(ver[7]);
3629 glVertex3dv(ver[4]);
3630 glEnd();
3631
3632 glBegin(GL_POLYGON);
3633 SphericalNormal(ver[3], normal), glNormal3dv(normal), glVertex3dv(ver[3]);
3634 SphericalNormal(ver[2], normal), glNormal3dv(normal), glVertex3dv(ver[2]);
3635 SphericalNormal(ver[6], normal), glNormal3dv(normal), glVertex3dv(ver[6]);
3636 SphericalNormal(ver[7], normal), glNormal3dv(normal), glVertex3dv(ver[7]);
3637 glEnd();
3638
3639 glBegin(GL_POLYGON);
3640 TMath::Normal2Plane(ver[5], ver[6], ver[2], normal);
3641 glNormal3dv(normal);
3642 glVertex3dv(ver[5]);
3643 glVertex3dv(ver[6]);
3644 glVertex3dv(ver[2]);
3645 glVertex3dv(ver[1]);
3646 glEnd();
3647
3648 glBegin(GL_POLYGON);
3649 SphericalNormalInv(ver[0], normal), glNormal3dv(normal), glVertex3dv(ver[0]);
3650 SphericalNormalInv(ver[4], normal), glNormal3dv(normal), glVertex3dv(ver[4]);
3651 SphericalNormalInv(ver[5], normal), glNormal3dv(normal), glVertex3dv(ver[5]);
3652 SphericalNormalInv(ver[1], normal), glNormal3dv(normal), glVertex3dv(ver[1]);
3653 glEnd();
3654}
3655
3656////////////////////////////////////////////////////////////////////////////////
3657
3658void DrawTrapezoidTextured(const Double_t ver[][3], Double_t texMin, Double_t texMax)
3659{
3660 Double_t normal[3] = {};
3661 if (texMin > texMax)
3662 std::swap(texMin, texMax);
3663
3664 const Double_t tex[] = {texMin, texMin, texMax, texMax, texMin, texMin, texMax, texMax};
3665 glBegin(GL_POLYGON);
3666 TMath::Normal2Plane(ver[0], ver[1], ver[2], normal);
3667 glNormal3dv(normal);
3668 glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
3669 glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
3670 glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
3671 glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
3672 glEnd();
3673 glBegin(GL_POLYGON);
3674 TMath::Normal2Plane(ver[4], ver[7], ver[6], normal);
3675 glNormal3dv(normal);
3676 glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
3677 glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
3678 glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
3679 glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
3680 glEnd();
3681 glBegin(GL_POLYGON);
3682 TMath::Normal2Plane(ver[0], ver[3], ver[7], normal);
3683 glNormal3dv(normal);
3684 glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
3685 glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
3686 glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
3687 glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
3688 glEnd();
3689 glBegin(GL_POLYGON);
3690 SphericalNormal(ver[3], normal), glNormal3dv(normal), glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
3691 SphericalNormal(ver[2], normal), glNormal3dv(normal), glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
3692 SphericalNormal(ver[6], normal), glNormal3dv(normal), glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
3693 SphericalNormal(ver[7], normal), glNormal3dv(normal), glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
3694 glEnd();
3695 glBegin(GL_POLYGON);
3696 TMath::Normal2Plane(ver[5], ver[6], ver[2], normal);
3697 glNormal3dv(normal);
3698 glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
3699 glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
3700 glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
3701 glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
3702 glEnd();
3703 glBegin(GL_POLYGON);
3704 SphericalNormalInv(ver[0], normal), glNormal3dv(normal), glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
3705 SphericalNormalInv(ver[4], normal), glNormal3dv(normal), glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
3706 SphericalNormalInv(ver[5], normal), glNormal3dv(normal), glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
3707 SphericalNormalInv(ver[1], normal), glNormal3dv(normal), glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
3708 glEnd();
3709}
3710
3711
3712void Draw2DAxis(TAxis *axis, Double_t xMin, Double_t yMin, Double_t xMax, Double_t yMax,
3713 Double_t min, Double_t max, Bool_t log, Bool_t z = kFALSE)
3714{
3715 //Axes are drawn with help of TGaxis class
3716 std::string option;
3717 option.reserve(20);
3718
3719 if (xMin > xMax || z) option += "SDH=+";
3720 else option += "SDH=-";
3721
3722 if (log) option += 'G';
3723
3724 Int_t nDiv = axis->GetNdivisions();
3725
3726 if (nDiv < 0) {
3727 option += 'N';
3728 nDiv = -nDiv;
3729 }
3730
3731 TGaxis axisPainter;
3732 axisPainter.SetLineWidth(1);
3733
3734 static const Double_t zero = 0.001;
3735
3736 if (TMath::Abs(xMax - xMin) >= zero || TMath::Abs(yMax - yMin) >= zero) {
3737 axisPainter.ImportAxisAttributes(axis);
3738 axisPainter.SetLabelOffset(axis->GetLabelOffset() + axis->GetTickLength());
3739
3740 if (log) {
3741 min = TMath::Power(10, min);
3742 max = TMath::Power(10, max);
3743 }
3744 //Option time display is required ?
3745 if (axis->GetTimeDisplay()) {
3746 option += 't';
3747
3748 if (!strlen(axis->GetTimeFormatOnly()))
3749 axisPainter.SetTimeFormat(axis->ChooseTimeFormat(max - min));
3750 else
3751 axisPainter.SetTimeFormat(axis->GetTimeFormat());
3752 }
3753
3754 axisPainter.SetOption(option.c_str());
3755 axisPainter.PaintAxis(xMin, yMin, xMax, yMax, min, max, nDiv, option.c_str());
3756 }
3757}
3758
3759const Int_t gFramePoints[][2] = {{3, 1}, {0, 2}, {1, 3}, {2, 0}};
3760//Each point has two "neighbouring axes" (left and right). Axes types are 1 (ordinata) and 0 (abscissa)
3761const Int_t gAxisType[][2] = {{1, 0}, {0, 1}, {1, 0}, {0, 1}};
3762
3763////////////////////////////////////////////////////////////////////////////////
3764///Using front point, find, where to draw axes and which labels to use for them
3765///gVirtualX->SelectWindow(gGLManager->GetVirtualXInd(fGLDevice));
3766///gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
3767
3768void DrawAxes(Int_t fp, const Int_t *vp, const TGLVertex3 *box, const TGLPlotCoordinates *coord,
3769 TAxis *xAxis, TAxis *yAxis, TAxis *zAxis)
3770{
3771 const Int_t left = gFramePoints[fp][0];
3772 const Int_t right = gFramePoints[fp][1];
3773 const Double_t xLeft = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
3774 + box[left].X() - vp[0]));
3775 const Double_t yLeft = gPad->AbsPixeltoY(Int_t(vp[3] - box[left].Y()
3776 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3777 * gPad->GetWh() + vp[1]));
3778 const Double_t xMid = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
3779 + box[fp].X() - vp[0]));
3780 const Double_t yMid = gPad->AbsPixeltoY(Int_t(vp[3] - box[fp].Y()
3781 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3782 * gPad->GetWh() + vp[1]));
3783 const Double_t xRight = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC()
3784 * gPad->GetWw() + box[right].X() - vp[0]));
3785 const Double_t yRight = gPad->AbsPixeltoY(Int_t(vp[3] - box[right].Y()
3786 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3787 * gPad->GetWh() + vp[1]));
3788 const Double_t points[][2] = {{coord->GetXRange().first, coord->GetYRange().first },
3789 {coord->GetXRange().second, coord->GetYRange().first },
3790 {coord->GetXRange().second, coord->GetYRange().second},
3791 {coord->GetXRange().first, coord->GetYRange().second}};
3792 const Int_t leftType = gAxisType[fp][0];
3793 const Int_t rightType = gAxisType[fp][1];
3794 const Double_t leftLabel = points[left][leftType];
3795 const Double_t leftMidLabel = points[fp][leftType];
3796 const Double_t rightMidLabel = points[fp][rightType];
3797 const Double_t rightLabel = points[right][rightType];
3798
3799 if (xLeft - xMid || yLeft - yMid) {//To suppress error messages from TGaxis
3800 TAxis *axis = leftType ? yAxis : xAxis;
3801 if (leftLabel < leftMidLabel)
3802 Draw2DAxis(axis, xLeft, yLeft, xMid, yMid, leftLabel, leftMidLabel,
3803 leftType ? coord->GetYLog() : coord->GetXLog());
3804 else
3805 Draw2DAxis(axis, xMid, yMid, xLeft, yLeft, leftMidLabel, leftLabel,
3806 leftType ? coord->GetYLog() : coord->GetXLog());
3807 }
3808
3809 if (xRight - xMid || yRight - yMid) {//To suppress error messages from TGaxis
3810 TAxis *axis = rightType ? yAxis : xAxis;
3811
3812 if (rightMidLabel < rightLabel)
3813 Draw2DAxis(axis, xMid, yMid, xRight, yRight, rightMidLabel, rightLabel,
3814 rightType ? coord->GetYLog() : coord->GetXLog());
3815 else
3816 Draw2DAxis(axis, xRight, yRight, xMid, yMid, rightLabel, rightMidLabel,
3817 rightType ? coord->GetYLog() : coord->GetXLog());
3818 }
3819
3820 const Double_t xUp = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
3821 + box[left + 4].X() - vp[0]));
3822 const Double_t yUp = gPad->AbsPixeltoY(Int_t(vp[3] - box[left + 4].Y()
3823 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3824 * gPad->GetWh() + vp[1]));
3825 Draw2DAxis(zAxis, xLeft, yLeft, xUp, yUp, coord->GetZRange().first,
3826 coord->GetZRange().second, coord->GetZLog(), kTRUE);
3827}
3828
3829void SetZLevels(TAxis *zAxis, Double_t zMin, Double_t zMax,
3830 Double_t zScale, std::vector<Double_t> &zLevels)
3831{
3832 Int_t nDiv = zAxis->GetNdivisions() % 100;
3833 Int_t nBins = 0;
3834 Double_t binLow = 0., binHigh = 0., binWidth = 0.;
3835 THLimitsFinder::Optimize(zMin, zMax, nDiv, binLow, binHigh, nBins, binWidth, " ");
3836 zLevels.resize(nBins + 1);
3837
3838 for (Int_t i = 0; i < nBins + 1; ++i)
3839 zLevels[i] = (binLow + i * binWidth) * zScale;
3840}
3841
3842////////////////////////////////////////////////////////////////////////////////
3843///Draw textured triangle
3844
3846 Double_t t1, Double_t t2, Double_t t3, const TGLVector3 &norm1,
3847 const TGLVector3 &norm2, const TGLVector3 &norm3)
3848{
3849 glBegin(GL_POLYGON);
3850 glNormal3dv(norm1.CArr());
3851 glTexCoord1d(t1);
3852 glVertex3dv(v1.CArr());
3853 glNormal3dv(norm2.CArr());
3854 glTexCoord1d(t2);
3855 glVertex3dv(v2.CArr());
3856 glNormal3dv(norm3.CArr());
3857 glTexCoord1d(t3);
3858 glVertex3dv(v3.CArr());
3859 glEnd();
3860}
3861
3862////////////////////////////////////////////////////////////////////////////////
3863///Draw textured triangle on a plane
3864
3867 const TGLVector3 &normal)
3868{
3869 glBegin(GL_POLYGON);
3870 glNormal3dv(normal.CArr());
3871 glTexCoord1d(t1);
3872 glVertex3d(v1.X(), v1.Y(), z);
3873 glTexCoord1d(t2);
3874 glVertex3d(v2.X(), v2.Y(), z);
3875 glTexCoord1d(t3);
3876 glVertex3d(v3.X(), v3.Y(), z);
3877 glEnd();
3878}
3879
3880////////////////////////////////////////////////////////////////////////////////
3881///This function creates color for parametric surface's vertex,
3882///using its 'u' value.
3883///I've found it in one of Apple's Carbon tutorials , and it's based
3884///on Paul Bourke work. Very nice colors!!! :)
3885
3887{
3888 Float_t dv,vmid;
3889 //Float_t c[] = {1.f, 1.f, 1.f};
3890 Float_t c1[3] = {}, c2[3] = {}, c3[3] = {};
3891 Float_t ratio ;
3892 rgba[3] = 1.f;
3893
3894 if (v < vmin)
3895 v = vmin;
3896 if (v > vmax)
3897 v = vmax;
3898 dv = vmax - vmin;
3899
3900 switch (type) {
3901 case 0:
3902 rgba[0] = 1.f;
3903 rgba[1] = 1.f;
3904 rgba[2] = 1.f;
3905 break;
3906 case 1:
3907 if (v < (vmin + 0.25 * dv)) {
3908 rgba[0] = 0;
3909 rgba[1] = 4 * (v - vmin) / dv;
3910 rgba[2] = 1;
3911 } else if (v < (vmin + 0.5 * dv)) {
3912 rgba[0] = 0;
3913 rgba[1] = 1;
3914 rgba[2] = 1 + 4 * (vmin + 0.25 * dv - v) / dv;
3915 } else if (v < (vmin + 0.75 * dv)) {
3916 rgba[0] = 4 * (v - vmin - 0.5 * dv) / dv;
3917 rgba[1] = 1;
3918 rgba[2] = 0;
3919 } else {
3920 rgba[0] = 1;
3921 rgba[1] = 1 + 4 * (vmin + 0.75 * dv - v) / dv;
3922 rgba[2] = 0;
3923 }
3924 break;
3925 case 2:
3926 rgba[0] = (v - vmin) / dv;
3927 rgba[1] = 0;
3928 rgba[2] = (vmax - v) / dv;
3929 break;
3930 case 3:
3931 rgba[0] = (v - vmin) / dv;
3932 rgba[1] = rgba[0];
3933 rgba[2] = rgba[0];
3934 break;
3935 case 4:
3936 if (v < (vmin + dv / 6.0)) {
3937 rgba[0] = 1;
3938 rgba[1] = 6 * (v - vmin) / dv;
3939 rgba[2] = 0;
3940 } else if (v < (vmin + 2.0 * dv / 6.0)) {
3941 rgba[0] = 1 + 6 * (vmin + dv / 6.0 - v) / dv;
3942 rgba[1] = 1;
3943 rgba[2] = 0;
3944 } else if (v < (vmin + 3.0 * dv / 6.0)) {
3945 rgba[0] = 0;
3946 rgba[1] = 1;
3947 rgba[2] = 6 * (v - vmin - 2.0 * dv / 6.0) / dv;
3948 } else if (v < (vmin + 4.0 * dv / 6.0)) {
3949 rgba[0] = 0;
3950 rgba[1] = 1 + 6 * (vmin + 3.0 * dv / 6.0 - v) / dv;
3951 rgba[2] = 1;
3952 } else if (v < (vmin + 5.0 * dv / 6.0)) {
3953 rgba[0] = 6 * (v - vmin - 4.0 * dv / 6.0) / dv;
3954 rgba[1] = 0;
3955 rgba[2] = 1;
3956 } else {
3957 rgba[0] = 1;
3958 rgba[1] = 0;
3959 rgba[2] = 1 + 6 * (vmin + 5.0 * dv / 6.0 - v) / dv;
3960 }
3961 break;
3962 case 5:
3963 rgba[0] = (v - vmin) / (vmax - vmin);
3964 rgba[1] = 1;
3965 rgba[2] = 0;
3966 break;
3967 case 6:
3968 rgba[0] = (v - vmin) / (vmax - vmin);
3969 rgba[1] = (vmax - v) / (vmax - vmin);
3970 rgba[2] = rgba[0];
3971 break;
3972 case 7:
3973 if (v < (vmin + 0.25 * dv)) {
3974 rgba[0] = 0;
3975 rgba[1] = 4 * (v - vmin) / dv;
3976 rgba[2] = 1 - rgba[1];
3977 } else if (v < (vmin + 0.5 * dv)) {
3978 rgba[0] = 4 * (v - vmin - 0.25 * dv) / dv;
3979 rgba[1] = 1 - rgba[0];
3980 rgba[2] = 0;
3981 } else if (v < (vmin + 0.75 * dv)) {
3982 rgba[1] = 4 * (v - vmin - 0.5 * dv) / dv;
3983 rgba[0] = 1 - rgba[1];
3984 rgba[2] = 0;
3985 } else {
3986 rgba[0] = 0;
3987 rgba[2] = 4 * (v - vmin - 0.75 * dv) / dv;
3988 rgba[1] = 1 - rgba[2];
3989 }
3990 break;
3991 case 8:
3992 if (v < (vmin + 0.5 * dv)) {
3993 rgba[0] = 2 * (v - vmin) / dv;
3994 rgba[1] = rgba[0];
3995 rgba[2] = rgba[0];
3996 } else {
3997 rgba[0] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
3998 rgba[1] = rgba[0];
3999 rgba[2] = rgba[0];
4000 }
4001 break;
4002 case 9:
4003 if (v < (vmin + dv / 3)) {
4004 rgba[2] = 3 * (v - vmin) / dv;
4005 rgba[1] = 0;
4006 rgba[0] = 1 - rgba[2];
4007 } else if (v < (vmin + 2 * dv / 3)) {
4008 rgba[0] = 0;
4009 rgba[1] = 3 * (v - vmin - dv / 3) / dv;
4010 rgba[2] = 1;
4011 } else {
4012 rgba[0] = 3 * (v - vmin - 2 * dv / 3) / dv;
4013 rgba[1] = 1 - rgba[0];
4014 rgba[2] = 1;
4015 }
4016 break;
4017 case 10:
4018 if (v < (vmin + 0.2 * dv)) {
4019 rgba[0] = 0;
4020 rgba[1] = 5 * (v - vmin) / dv;
4021 rgba[2] = 1;
4022 } else if (v < (vmin + 0.4 * dv)) {
4023 rgba[0] = 0;
4024 rgba[1] = 1;
4025 rgba[2] = 1 + 5 * (vmin + 0.2 * dv - v) / dv;
4026 } else if (v < (vmin + 0.6 * dv)) {
4027 rgba[0] = 5 * (v - vmin - 0.4 * dv) / dv;
4028 rgba[1] = 1;
4029 rgba[2] = 0;
4030 } else if (v < (vmin + 0.8 * dv)) {
4031 rgba[0] = 1;
4032 rgba[1] = 1 - 5 * (v - vmin - 0.6 * dv) / dv;
4033 rgba[2] = 0;
4034 } else {
4035 rgba[0] = 1;
4036 rgba[1] = 5 * (v - vmin - 0.8 * dv) / dv;
4037 rgba[2] = 5 * (v - vmin - 0.8 * dv) / dv;
4038 }
4039 break;
4040 case 11:
4041 c1[0] = 200 / 255.0; c1[1] = 60 / 255.0; c1[2] = 0 / 255.0;
4042 c2[0] = 250 / 255.0; c2[1] = 160 / 255.0; c2[2] = 110 / 255.0;
4043 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / dv + c1[0];
4044 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / dv + c1[1];
4045 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / dv + c1[2];
4046 break;
4047 case 12:
4048 c1[0] = 55 / 255.0; c1[1] = 55 / 255.0; c1[2] = 45 / 255.0;
4049 c2[0] = 200 / 255.0; c2[1] = 60 / 255.0; c2[2] = 0 / 255.0;
4050 c3[0] = 250 / 255.0; c3[1] = 160 / 255.0; c3[2] = 110 / 255.0;
4051 ratio = 0.4;
4052 vmid = vmin + ratio * dv;
4053 if (v < vmid) {
4054 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
4055 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
4056 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
4057 } else {
4058 rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
4059 rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
4060 rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
4061 }
4062 break;
4063 case 13:
4064 c1[0] = 0 / 255.0; c1[1] = 255 / 255.0; c1[2] = 0 / 255.0;
4065 c2[0] = 255 / 255.0; c2[1] = 150 / 255.0; c2[2] = 0 / 255.0;
4066 c3[0] = 255 / 255.0; c3[1] = 250 / 255.0; c3[2] = 240 / 255.0;
4067 ratio = 0.3;
4068 vmid = vmin + ratio * dv;
4069 if (v < vmid) {
4070 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
4071 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
4072 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
4073 } else {
4074 rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
4075 rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
4076 rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
4077 }
4078 break;
4079 case 14:
4080 rgba[0] = 1;
4081 rgba[1] = 1 - (v - vmin) / dv;
4082 rgba[2] = 0;
4083 break;
4084 case 15:
4085 if (v < (vmin + 0.25 * dv)) {
4086 rgba[0] = 0;
4087 rgba[1] = 4 * (v - vmin) / dv;
4088 rgba[2] = 1;
4089 } else if (v < (vmin + 0.5 * dv)) {
4090 rgba[0] = 0;
4091 rgba[1] = 1;
4092 rgba[2] = 1 - 4 * (v - vmin - 0.25 * dv) / dv;
4093 } else if (v < (vmin + 0.75 * dv)) {
4094 rgba[0] = 4 * (v - vmin - 0.5 * dv) / dv;
4095 rgba[1] = 1;
4096 rgba[2] = 0;
4097 } else {
4098 rgba[0] = 1;
4099 rgba[1] = 1;
4100 rgba[2] = 4 * (v - vmin - 0.75 * dv) / dv;
4101 }
4102 break;
4103 case 16:
4104 if (v < (vmin + 0.5 * dv)) {
4105 rgba[0] = 0.0;
4106 rgba[1] = 2 * (v - vmin) / dv;
4107 rgba[2] = 1 - 2 * (v - vmin) / dv;
4108 } else {
4109 rgba[0] = 2 * (v - vmin - 0.5 * dv) / dv;
4110 rgba[1] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
4111 rgba[2] = 0.0;
4112 }
4113 break;
4114 case 17:
4115 if (v < (vmin + 0.5 * dv)) {
4116 rgba[0] = 1.0;
4117 rgba[1] = 1 - 2 * (v - vmin) / dv;
4118 rgba[2] = 2 * (v - vmin) / dv;
4119 } else {
4120 rgba[0] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
4121 rgba[1] = 2 * (v - vmin - 0.5 * dv) / dv;
4122 rgba[2] = 1.0;
4123 }
4124 break;
4125 case 18:
4126 rgba[0] = 0;
4127 rgba[1] = (v - vmin) / (vmax - vmin);
4128 rgba[2] = 1;
4129 break;
4130 case 19:
4131 rgba[0] = (v - vmin) / (vmax - vmin);
4132 rgba[1] = rgba[0];
4133 rgba[2] = 1;
4134 break;
4135 case 20:
4136 c1[0] = 0 / 255.0; c1[1] = 160 / 255.0; c1[2] = 0 / 255.0;
4137 c2[0] = 180 / 255.0; c2[1] = 220 / 255.0; c2[2] = 0 / 255.0;
4138 c3[0] = 250 / 255.0; c3[1] = 220 / 255.0; c3[2] = 170 / 255.0;
4139 ratio = 0.3;
4140 vmid = vmin + ratio * dv;
4141 if (v < vmid) {
4142 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
4143 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
4144 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
4145 } else {
4146 rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
4147 rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
4148 rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
4149 }
4150 break;
4151 }
4152}
4153
4154}
4155
4156////////////////////////////////////////////////////////////////////////////////
4157///Ctor.
4158
4160 : fContours(0),
4161 fPaletteSize(0),
4162 fTexture(0),
4163 fMaxPaletteSize(0)
4164{
4165}
4166
4167////////////////////////////////////////////////////////////////////////////////
4168///Try to find colors for palette.
4169
4171{
4172 if (!fMaxPaletteSize && check)
4173 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &fMaxPaletteSize);
4174
4175 if (!(zRange.second - zRange.first))
4176 return kFALSE;
4177
4178 if (!paletteSize) {
4179 Error("TGLLevelPaletter::GeneratePalette",
4180 "Invalid palette size, must be a positive number");
4181 return kFALSE;
4182 }
4183
4184 if (check && paletteSize > UInt_t(fMaxPaletteSize)) {
4185 Error("TGLLevelPalette::GeneratePalette",
4186 "Number of contours %d is too big for GL 1D texture, try to reduce it to %d",
4187 paletteSize, fMaxPaletteSize);
4188 return kFALSE;
4189 }
4190
4191 UInt_t nearestPow2 = 2;
4192 while (nearestPow2 < paletteSize)
4193 nearestPow2 <<= 1;
4194
4195 fTexels.resize(4 * nearestPow2);
4196 fPaletteSize = paletteSize;
4197
4198 //Generate texels.
4199 const Int_t nColors = gStyle->GetNumberOfColors();
4200
4201 //Map color index into index in real palette.
4202
4203 for (UInt_t i = 0; i < paletteSize; ++i) {
4204 Int_t paletteInd = Int_t(nColors / Double_t(paletteSize) * i);
4205 if (paletteInd > nColors - 1)
4206 paletteInd = nColors - 1;
4207 Int_t colorInd = gStyle->GetColorPalette(paletteInd);
4208
4209 if (const TColor *c = gROOT->GetColor(colorInd)) {
4210 Float_t rgb[3] = {};
4211 c->GetRGB(rgb[0], rgb[1], rgb[2]);
4212 fTexels[i * 4] = UChar_t(rgb[0] * 255);
4213 fTexels[i * 4 + 1] = UChar_t(rgb[1] * 255);
4214 fTexels[i * 4 + 2] = UChar_t(rgb[2] * 255);
4215 fTexels[i * 4 + 3] = 200;//alpha
4216 }
4217 }
4218
4219 fZRange = zRange;
4220
4221 return kTRUE;
4222}
4223
4224////////////////////////////////////////////////////////////////////////////////
4225///Clear :)
4226
4227void TGLLevelPalette::SetContours(const std::vector<Double_t> *cont)
4228{
4229 fContours = cont;
4230}
4231
4232////////////////////////////////////////////////////////////////////////////////
4233///Enable 1D texture
4234
4236{
4237 glEnable(GL_TEXTURE_1D);
4238
4239 glGenTextures(1, &fTexture);
4240
4241 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4242 glBindTexture(GL_TEXTURE_1D, fTexture);
4243 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
4244 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4245 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4246 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, fTexels.size() / 4, 0,
4247 GL_RGBA, GL_UNSIGNED_BYTE, &fTexels[0]);
4248 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GLint(mode));
4249}
4250
4251////////////////////////////////////////////////////////////////////////////////
4252///Disable 1D texture
4253
4255{
4256 glDeleteTextures(1, &fTexture);
4257 glDisable(GL_TEXTURE_1D);
4258}
4259
4260////////////////////////////////////////////////////////////////////////////////
4261///Get. Palette. Size.
4262
4264{
4265 return Int_t(fPaletteSize);
4266}
4267
4268////////////////////////////////////////////////////////////////////////////////
4269///Get tex coordinate
4270
4272{
4273 if (!fContours) {
4274 if (z - fZRange.first < 0)
4275 z = fZRange.first;
4276 else if (fZRange.second < z)
4277 z = fZRange.second;
4278
4279 return (z - fZRange.first) / (fZRange.second - fZRange.first) * fPaletteSize / (fTexels.size() / 4);
4280 }
4281 /*
4282 //This part is wrong. To be fixed.
4283 std::vector<Double_t>::size_type i = 0, e = fContours->size();
4284
4285 if (!e)
4286 return 0.;
4287
4288 for (; i < e - 1; ++i) {
4289 if (z >= (*fContours)[i] && z <= (*fContours)[i + 1])
4290 return i / Double_t(fTexels.size() / 4);
4291 }
4292 */
4293
4294 return 1.;
4295}
4296
4297////////////////////////////////////////////////////////////////////////////////
4298///Get color.
4299
4301{
4302 if (z - fZRange.first < 0)
4303 z = fZRange.first;
4304 else if (fZRange.second < z)
4305 z = fZRange.second;
4306
4307 UInt_t ind = UInt_t((z - fZRange.first) / (fZRange.second - fZRange.first) * fPaletteSize);
4308 if (ind >= fPaletteSize)
4309 ind = fPaletteSize - 1;
4310
4311 return &fTexels[ind * 4];
4312}
4313
4314////////////////////////////////////////////////////////////////////////////////
4315///Get color.
4316
4318{
4319 return &fTexels[ind * 4];
4320}
#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
#define GLU_VERTEX
Definition: GL_glu.h:210
void gluTessCallback(GLUtesselator *tess, GLenum which, _GLUfuncptr CallBackFunc)
Definition: tess.c:286
#define GL_LINE_STRIP
Definition: GL_glu.h:286
#define GL_LINES
Definition: GL_glu.h:284
int GLint
Definition: GL_glu.h:272
void gluDeleteTess(GLUtesselator *tess)
Definition: tess.c:203
GLUtesselator * gluNewTess(void)
Definition: tess.c:102
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
#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
#define GL_QUAD_STRIP
Definition: GL_glu.h:291
#define d(i)
Definition: RSha256.hxx:102
#define c(i)
Definition: RSha256.hxx:101
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition: RtypesCore.h:63
unsigned short UShort_t
Definition: RtypesCore.h:40
int Int_t
Definition: RtypesCore.h:45
short Color_t
Definition: RtypesCore.h:92
unsigned char UChar_t
Definition: RtypesCore.h:38
char Char_t
Definition: RtypesCore.h:37
const Bool_t kFALSE
Definition: RtypesCore.h:101
unsigned int UInt_t
Definition: RtypesCore.h:46
float Float_t
Definition: RtypesCore.h:57
double Double_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:375
Bool_t operator<(const TDatime &d1, const TDatime &d2)
Definition: TDatime.h:106
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:1438
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
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void pixel
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t g
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t style
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
Option_t Option_t TPoint TPoint const char y1
#define gROOT
Definition: TROOT.h:404
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition: TString.cxx:2456
R__EXTERN TStyle * gStyle
Definition: TStyle.h:414
#define gPad
Definition: TVirtualPad.h:288
#define gVirtualX
Definition: TVirtualX.h:338
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:127
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:132
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Definition: TAxis.cxx:599
virtual const char * GetTimeFormat() const
Definition: TAxis.h:128
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:1823
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
void Scale(Double_t factor)
Isotropically scale bounding box along it's LOCAL axes, preserving center.
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 ViewportDeltaToWorld(const TGLVertex3 &worldRef, Double_t viewportXDelta, Double_t viewportYDelta, TGLMatrix *modviewMat=nullptr) const
Apply a 2D viewport delta (shift) to the projection of worldRef onto viewport, returning the resultan...
Definition: TGLCamera.cxx:546
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
~TGLCapabilityEnabler()
Destructor - reset state if changed.
Definition: TGLUtil.cxx:2728
TGLCapabilityEnabler(const TGLCapabilityEnabler &)
TGLCapabilitySwitch(const TGLCapabilitySwitch &)
void SetState(Bool_t s)
Definition: TGLUtil.cxx:2705
~TGLCapabilitySwitch()
Destructor - reset state if changed.
Definition: TGLUtil.cxx:2697
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:2782
TGLDisableGuard(Int_t cap)
TGLDisableGuard constructor.
Definition: TGLUtil.cxx:2773
~TGLEnableGuard()
TGLEnableGuard destructor.
Definition: TGLUtil.cxx:2765
TGLEnableGuard(Int_t cap)
TGLEnableGuard constructor.
Definition: TGLUtil.cxx:2756
Bool_t fFlip
Definition: TGLUtil.h:1106
void(* fFoo)(Float_t)
Definition: TGLUtil.h:1107
TGLFloatHolder(const TGLFloatHolder &)
Float_t fState
Definition: TGLUtil.h:1105
const UChar_t * GetColour(Double_t z) const
Get color.
Definition: TGLUtil.cxx:4300
const std::vector< Double_t > * fContours
Definition: TGLUtil.h:1349
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition: TGLUtil.cxx:4263
void SetContours(const std::vector< Double_t > *contours)
Clear :)
Definition: TGLUtil.cxx:4227
UInt_t fPaletteSize
Definition: TGLUtil.h:1350
TGLLevelPalette()
Ctor.
Definition: TGLUtil.cxx:4159
std::vector< UChar_t > fTexels
Definition: TGLUtil.h:1348
void DisableTexture() const
Disable 1D texture.
Definition: TGLUtil.cxx:4254
Double_t GetTexCoord(Double_t z) const
Get tex coordinate.
Definition: TGLUtil.cxx:4271
Rgl::Range_t fZRange
Definition: TGLUtil.h:1353
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition: TGLUtil.cxx:4170
Int_t fMaxPaletteSize
Definition: TGLUtil.h:1352
UInt_t fTexture
Definition: TGLUtil.h:1351
void EnableTexture(Int_t mode) const
Enable 1D texture.
Definition: TGLUtil.cxx:4235
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 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 Set(const TGLVertex3 &origin, const TGLVector3 &zAxis, const TGLVector3 &xAxis=nullptr)
Set matrix which when applied puts local origin at 'origin' and the local Z axis in direction 'z'.
Definition: TGLUtil.cxx:736
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:2835
void ReadColorBuffer(Int_t width, Int_t height)
Read color buffer.
Definition: TGLUtil.cxx:2811
virtual ~TGLSelectionBuffer()
TGLSelectionBuffer destructor.
Definition: TGLUtil.cxx:2804
TGLSelectionBuffer()
TGLSelectionBuffer constructor.
Definition: TGLUtil.cxx:2796
std::vector< UChar_t > fBuffer
Definition: TGLUtil.h:1141
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:2357
static void Color4ubv(const UChar_t *rgba)
Wrapper for glColor4ubv.
Definition: TGLUtil.cxx:1779
static UInt_t GetDrawQuality()
static: get draw quality
Definition: TGLUtil.cxx:1605
static Int_t fgPickingRadius
Definition: TGLUtil.h:929
static const UChar_t fgWhite[4]
Definition: TGLUtil.h:1060
static UInt_t fgDefaultDrawQuality
Definition: TGLUtil.h:917
static void SetDrawQuality(UInt_t dq)
static: set draw quality
Definition: TGLUtil.cxx:1613
static Float_t GetPointSizeScale()
Get global point-size scale.
Definition: TGLUtil.cxx:1883
static void Color3f(Float_t r, Float_t g, Float_t b)
Wrapper for glColor3f.
Definition: TGLUtil.cxx:1787
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:1621
static Float_t fgSimpleAxisWidthScale
Definition: TGLUtil.h:931
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:1689
static void Color3fv(const Float_t *rgb)
Wrapper for glColor3fv.
Definition: TGLUtil.cxx:1803
static void SetLineWidthScale(Float_t scale)
Set global line-width scale.
Definition: TGLUtil.cxx:1907
static void SetSimpleAxisWidthScale(Float_t s)
Definition: TGLUtil.cxx:1427
static UInt_t LockColor()
Prevent further color changes.
Definition: TGLUtil.cxx:1669
static void Color4f(Float_t r, Float_t g, Float_t b, Float_t a)
Wrapper for glColor4f.
Definition: TGLUtil.cxx:1795
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:2336
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:1741
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:2272
static const UChar_t fgRed[4]
Definition: TGLUtil.h:1056
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:2252
static UInt_t GetDefaultDrawQuality()
static: get default draw quality
Definition: TGLUtil.cxx:1629
static void BeginExtendPickRegion(Float_t scale)
Definition: TGLUtil.cxx:1952
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition: TGLUtil.cxx:1582
ELineHeadShape
Definition: TGLUtil.h:951
@ kLineHeadNone
Definition: TGLUtil.h:951
@ kLineHeadBox
Definition: TGLUtil.h:951
@ kLineHeadArrow
Definition: TGLUtil.h:951
static Float_t GetLineWidthScale()
Returns global line-width scale.
Definition: TGLUtil.cxx:1899
static Float_t fgPointLineScalingFactor
Definition: TGLUtil.h:928
static UInt_t UnlockColor()
Allow color changes.
Definition: TGLUtil.cxx:1677
static void EndAttLine(Int_t pick_radius=0, Bool_t selection=kFALSE)
Restore previous line drawing state.
Definition: TGLUtil.cxx:2308
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:2372
static void Color(const TGLColor &color)
Set color from TGLColor.
Definition: TGLUtil.cxx:1697
static void DrawReferenceMarker(const TGLCamera &camera, const TGLVertex3 &pos, Float_t radius=3, const UChar_t *rgba=nullptr)
Draw a sphere- marker on world-coordinate 'pos' with pixel radius 'radius'.
Definition: TGLUtil.cxx:2479
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:2438
static void Color3ubv(const UChar_t *rgb)
Wrapper for glColor3ubv.
Definition: TGLUtil.cxx:1771
static Int_t CheckError(const char *loc)
Check current GL error state, outputting details via ROOT Error method if one.
Definition: TGLUtil.cxx:1646
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition: TGLUtil.cxx:1852
static void ColorAlpha(const TGLColor &color, UChar_t alpha)
Set color from TGLColor and alpha value.
Definition: TGLUtil.cxx:1705
static Int_t GetPickingRadius()
Returns picking radius.
Definition: TGLUtil.cxx:1871
static void SetPointSizeScale(Float_t scale)
Set global point-size scale.
Definition: TGLUtil.cxx:1891
static void Color4fv(const Float_t *rgba)
Wrapper for glColor4fv.
Definition: TGLUtil.cxx:1811
static void Color3ub(UChar_t r, UChar_t g, UChar_t b)
Wrapper for glColor3ub.
Definition: TGLUtil.cxx:1755
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:1561
static const UChar_t fgBlue[4]
Definition: TGLUtil.h:1058
static const UChar_t fgGrey[4]
Definition: TGLUtil.h:1061
@ kAxesNone
Definition: TGLUtil.h:952
@ kAxesOrigin
Definition: TGLUtil.h:952
static Float_t PointSize()
Get the point-size, taking the global scaling into account.
Definition: TGLUtil.cxx:1935
static void EndExtendPickRegion()
Definition: TGLUtil.cxx:1967
static GLUtesselator * GetDrawTesselator3dv()
Returns a tesselator for direct drawing when using 3-vertices with double precision.
Definition: TGLUtil.cxx:1540
static GLUtesselator * GetDrawTesselator4fv()
Returns a tesselator for direct drawing when using 4-vertices with single precision.
Definition: TGLUtil.cxx:1519
static Float_t fgSimpleAxisBBoxScale
Definition: TGLUtil.h:932
static const UChar_t fgGreen[4]
Definition: TGLUtil.h:1057
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:1498
static void DrawSimpleAxes(const TGLCamera &camera, const TGLBoundingBox &bbox, Int_t axesType, Float_t labelScale=1)
Draw simple xyz-axes for given bounding-box.
Definition: TGLUtil.cxx:2494
static void SetSimpleAxisBBoxScale(Float_t s)
Definition: TGLUtil.cxx:1428
static void SetDefaultDrawQuality(UInt_t dq)
static: set default draw quality
Definition: TGLUtil.cxx:1637
static void PointToViewport(Int_t &x, Int_t &y)
Convert from point/screen coordinates to GL viewport coordinates.
Definition: TGLUtil.cxx:1823
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:2637
static Float_t LineWidth()
Get the line-width, taking the global scaling into account.
Definition: TGLUtil.cxx:1943
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:1980
static const UChar_t fgYellow[4]
Definition: TGLUtil.h:1059
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:2020
static Float_t GetPointLineScalingFactor()
Return extra scaling factor for points and lines.
Definition: TGLUtil.cxx:1863
static void Color4ub(UChar_t r, UChar_t g, UChar_t b, UChar_t a)
Wrapper for glColor4ub.
Definition: TGLUtil.cxx:1763
static void RenderCrosses(const TAttMarker &marker, Float_t *p, Int_t n, Bool_t sec_selection=kFALSE)
Render markers as crosses.
Definition: TGLUtil.cxx:2140
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:2818
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:1009
void SetLabelOffset(Float_t labeloffset)
Definition: TGaxis.h:109