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