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