Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGLPadPainter.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Timur Pocheptsov 06/05/2009
3
4/*************************************************************************
5 * Copyright (C) 1995-2009, 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 <stdexcept>
13#include <cassert>
14#include <limits>
15#include <memory>
16#include <vector>
17
18#include "TAttMarker.h"
19#include "TVirtualX.h"
20#include "TError.h"
21#include "TImage.h"
22#include "TROOT.h"
23#include "TPad.h"
24#include "TCanvas.h"
25
26#include "TColorGradient.h"
27#include "TGLPadPainter.h"
28#include "TGLIncludes.h"
29#include "TGLUtil.h"
30#include "TMath.h"
31
32#include <glad/gl.h>
33
34namespace {
35
36////////////////////////////////////////////////////////////////////////////////
37///Not a bad idea to assert on gVirtualX != nullptr
38
40{
41 return dynamic_cast<TColorGradient *>(gROOT->GetColor(fillColorIndex));
42}
43
44}
45
46/** \class TGLPadPainter
47\ingroup opengl
48"Delegating" part of TGLPadPainter. Line/fill/etc. attributes can be
49set inside TPad, but not only there:
50many of them are set by base sub-objects of 2d primitives
51(2d primitives usually inherit TAttLine or TAttFill etc.). And these sub-objects
52call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
53it will be mess - at any moment I do not know, where to take line attribute - from
54gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
55*/
56
57
58////////////////////////////////////////////////////////////////////////////////
59
61 : fIsHollowArea(kFALSE),
62 fLocked(kTRUE)
63{
64 fVp[0] = fVp[1] = fVp[2] = fVp[3] = 0;
65 fWinContext = 0;
66}
67
68
69////////////////////////////////////////////////////////////////////////////////
70///Delegate to gVirtualX.
71
73{
74 return gVirtualX->GetLineColor();
75}
76
77////////////////////////////////////////////////////////////////////////////////
78///Delegate to gVirtualX.
79
81{
82 return gVirtualX->GetLineStyle();
83}
84
85////////////////////////////////////////////////////////////////////////////////
86///Delegate to gVirtualX.
87
89{
90 return gVirtualX->GetLineWidth();
91}
92
93////////////////////////////////////////////////////////////////////////////////
94///Delegate to gVirtualX.
95
100
101////////////////////////////////////////////////////////////////////////////////
102///Delegate to gVirtualX.
103
105{
106 gVirtualX->SetLineStyle(lstyle);
107}
108
109////////////////////////////////////////////////////////////////////////////////
110///Delegate to gVirtualX.
111
113{
114 gVirtualX->SetLineWidth(lwidth);
115}
116
117////////////////////////////////////////////////////////////////////////////////
118///Delegate to gVirtualX.
119
121{
122 return gVirtualX->GetFillColor();
123}
124
125////////////////////////////////////////////////////////////////////////////////
126///Delegate to gVirtualX.
127
129{
130 return gVirtualX->GetFillStyle();
131}
132
133////////////////////////////////////////////////////////////////////////////////
134///Delegate to gVirtualX.
135///IsTransparent is implemented as inline function in TAttFill.
136
138{
139 return gVirtualX->IsTransparent();
140}
141
142////////////////////////////////////////////////////////////////////////////////
143///Delegate to gVirtualX.
144
146{
147 gVirtualX->SetFillColor(fcolor);
148}
149
150////////////////////////////////////////////////////////////////////////////////
151///Delegate to gVirtualX.
152
154{
155 gVirtualX->SetFillStyle(fstyle);
156}
157
158////////////////////////////////////////////////////////////////////////////////
159///Delegate to gVirtualX.
160
162{
163 gVirtualX->SetOpacity(percent);
164}
165
166////////////////////////////////////////////////////////////////////////////////
167///Delegate to gVirtualX.
168
170{
171 return gVirtualX->GetTextAlign();
172}
173
174////////////////////////////////////////////////////////////////////////////////
175///Delegate to gVirtualX.
176
178{
179 return gVirtualX->GetTextAngle();
180}
181
182////////////////////////////////////////////////////////////////////////////////
183///Delegate to gVirtualX.
184
186{
187 return gVirtualX->GetTextColor();
188}
189
190////////////////////////////////////////////////////////////////////////////////
191///Delegate to gVirtualX.
192
194{
195 return gVirtualX->GetTextFont();
196}
197
198////////////////////////////////////////////////////////////////////////////////
199///Delegate to gVirtualX.
200
202{
203 return gVirtualX->GetTextSize();
204}
205
206////////////////////////////////////////////////////////////////////////////////
207///Delegate to gVirtualX.
208
210{
211 return gVirtualX->GetTextMagnitude();
212}
213
214////////////////////////////////////////////////////////////////////////////////
215///Delegate to gVirtualX.
216
218{
219 gVirtualX->SetTextAlign(align);
220}
221
222////////////////////////////////////////////////////////////////////////////////
223///Delegate to gVirtualX.
224
226{
227 gVirtualX->SetTextAngle(tangle);
228}
229
230////////////////////////////////////////////////////////////////////////////////
231///Delegate to gVirtualX.
232
234{
235 gVirtualX->SetTextColor(tcolor);
236}
237
238////////////////////////////////////////////////////////////////////////////////
239///Delegate to gVirtualX.
240
242{
243 gVirtualX->SetTextFont(tfont);
244}
245
246////////////////////////////////////////////////////////////////////////////////
247///Delegate to gVirtualX.
248
250{
251 gVirtualX->SetTextSize(tsize);
252}
253
254////////////////////////////////////////////////////////////////////////////////
255///Delegate to gVirtualX.
256
258{
259 gVirtualX->SetTextSizePixels(npixels);
260}
261
262
263////////////////////////////////////////////////////////////////////////////////
264/// Delegate to gVirtualX.
265
267{
268 return gVirtualX->GetMarkerColor();
269}
270
271
272////////////////////////////////////////////////////////////////////////////////
273/// Delegate to gVirtualX.
274
276{
277 return gVirtualX->GetMarkerStyle();
278}
279
280
281////////////////////////////////////////////////////////////////////////////////
282/// Delegate to gVirtualX.
283
285{
286 return gVirtualX->GetMarkerSize();
287}
288
289
290////////////////////////////////////////////////////////////////////////////////
291/// Delegate to gVirtualX.
292
294{
295 gVirtualX->SetMarkerColor(mcolor);
296}
297
298
299////////////////////////////////////////////////////////////////////////////////
300/// Delegate to gVirtualX.
301
303{
304 gVirtualX->SetMarkerStyle(mstyle);
305}
306
307
308////////////////////////////////////////////////////////////////////////////////
309/// Delegate to gVirtualX.
310
312{
313 gVirtualX->SetMarkerSize(msize);
314}
315
316/*
317"Pixmap" part of TGLPadPainter.
318*/
319
320////////////////////////////////////////////////////////////////////////////////
321///Not required at the moment.
322
324{
325 // return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
326 return 0;
327}
328
329////////////////////////////////////////////////////////////////////////////////
330/// Resize a gVirtualX Pixmap.
331
333{
334 return gVirtualX->ResizePixmap(device, w, h);
335}
336
337////////////////////////////////////////////////////////////////////////////////
338/// Call gVirtualX->ClearWindow()
339
341{
342 gVirtualX->ClearWindow();
343}
344
345////////////////////////////////////////////////////////////////////////////////
346/// Returns true when cocoa backend is used
347
349{
350 return gVirtualX->InheritsFrom("TGCocoa");
351}
352
353////////////////////////////////////////////////////////////////////////////////
354///Not required at the moment.
355
356void TGLPadPainter::CopyDrawable(Int_t /* device */, Int_t /* px */, Int_t /* py */)
357{
358 // gVirtualX->CopyPixmap(device, px, py);
359}
360
361////////////////////////////////////////////////////////////////////////////////
362///Not required at the moment.
363
365{
366 // gVirtualX->SelectWindow(device);
367 // gVirtualX->ClosePixmap();
368 fWinContext = 0;
369}
370
371////////////////////////////////////////////////////////////////////////////////
372///For gVirtualX this means select pixmap (or window)
373///and all subsequent drawings will go into
374///this pixmap. For OpenGL this means the change of
375///coordinate system and viewport.
376
378{
379 if (fLocked)
380 return;
381
382 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
383 // GL painter does not use proper id for sub-pads (see CreateDrawable)
384 // so one always use canvas ID to execute TVirtualX-specific commands
385 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
386
387 Int_t px = 0, py = 0;
388
389 pad->XYtoAbsPixel(pad->GetX1(), pad->GetY1(), px, py);
390
391 py = gPad->GetWh() - py;
392 //
395
396 glViewport(GLint(px * scale), GLint(py * scale),
397 GLsizei(gPad->GetWw() * pad->GetAbsWNDC() * scale),
398 GLsizei(gPad->GetWh() * pad->GetAbsHNDC() * scale));
399
402 glOrtho(pad->GetX1(), pad->GetX2(), pad->GetY1(), pad->GetY2(), -10., 10.);
403
406 glTranslated(0., 0., -1.);
407 } else {
408 ::Error("TGLPadPainter::SelectDrawable",
409 "function was called not from TPad or TCanvas code\n");
410 throw std::runtime_error("");
411 }
412}
413
414////////////////////////////////////////////////////////////////////////////////
415/// Call low-level update of selected drawable, redirect to gVirtualX.
416
418{
419 if (fWinContext)
420 gVirtualX->UpdateWindowW(fWinContext, mode);
421}
422
423
424////////////////////////////////////////////////////////////////////////////////
425/// Set drawing mode for specified device
426
428{
429 auto ctxt = fWinContext;
430 if (device)
431 ctxt = gVirtualX->GetWindowContext(device);
432 if (ctxt)
433 gVirtualX->SetDrawModeW(ctxt, (TVirtualX::EDrawMode) mode);
434}
435
436////////////////////////////////////////////////////////////////////////////////
437///Init gl-pad painter:
438///1. 2D painter does not use depth test, should not modify
439/// depth-buffer content (except initial cleanup).
440///2. Disable cull face.
441///3. Disable lighting.
442///4. Set viewport (to the whole canvas area).
443///5. Set camera.
444///6. Unlock painter.
445
447{
448 static bool gl_init = false;
449 if (!gl_init) {
451 if (version == 0)
452 Warning("TGLPadPainter::InitPainter", "GL initalization failed.");
453 else if (gDebug > 0)
454 Info("TGLPadPainter::InitPainter", "GL initalization successful.");
455 gl_init = true;
456 }
460
461 //Clear the buffer
462 glViewport(0, 0, GLsizei(gPad->GetWw()), GLsizei(gPad->GetWh()));
463
465 glClearColor(1.,1.,1.,1.);
468
471
472 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
473
476 glTranslated(0., 0., -1.);
477
478 fLocked = kFALSE;
479}
480
481////////////////////////////////////////////////////////////////////////////////
482///When TPad::Range for gPad is called, projection
483///must be changed in OpenGL.
484
486{
487 if (fLocked) return;
488
491
492 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
493
495}
496
497////////////////////////////////////////////////////////////////////////////////
498///Locked state of painter means, that
499///GL context can be invalid, so no GL calls
500///can be executed.
501
503{
504 if (fLocked) return;
505
506 glFinish();
507 fLocked = kTRUE;
508}
509
510/*
5112D primitives.
512*/
513
515
516////////////////////////////////////////////////////////////////////////////////
517///Draw line segment.
518
520{
521 if (fLocked) {
522 //GL pad painter can be called in non-standard situation:
523 //not from TPad::Paint, but
524 //from TView3D::ExecuteRotateView. This means in fact,
525 //that TView3D wants to draw itself in a XOR mode, via
526 //gVirtualX.
527 if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) {
528 gVirtualX->DrawLineW(fWinContext,
529 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
530 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2));
531 }
532
533 return;
534 }
535
537
538 glBegin(GL_LINES);
539 glVertex2d(x1, y1);
540 glVertex2d(x2, y2);
541 glEnd();
542
543 if (gVirtualX->GetLineWidth() > lineWidthTS) {
544 Double_t pointSize = gVirtualX->GetLineWidth();
550 glBegin(GL_POINTS);
551
552 glVertex2d(x1, y1);
553 glVertex2d(x2, y2);
554
555 glEnd();
556 glPointSize(1.f);
557 }
558
559}
560
561////////////////////////////////////////////////////////////////////////////////
562///Draw line segment in NDC coordinates.
563
565{
566 if (fLocked) {
567 // this code used when crosshair cursor is drawn
568 if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) {
569 const Int_t px1 = gPad->UtoPixel(u1);
570 const Int_t py1 = gPad->VtoPixel(v1);
571 const Int_t px2 = gPad->UtoPixel(u2);
572 const Int_t py2 = gPad->VtoPixel(v2);
573 gVirtualX->DrawLineW(fWinContext, px1, py1, px2, py2);
574 }
575 return;
576 }
577
579 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
580 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
581
582 glBegin(GL_LINES);
583 glVertex2d(gPad->GetX1() + u1 * xRange, gPad->GetY1() + v1 * yRange);
584 glVertex2d(gPad->GetX1() + u2 * xRange, gPad->GetY1() + v2 * yRange);
585 glEnd();
586}
587
588////////////////////////////////////////////////////////////////////////////////
589///Draw filled or hollow box.
590
592{
593 if (fLocked) return;
594
595 if (IsGradientFill(gVirtualX->GetFillColor())) {
596 Double_t xs[] = {x1, x2, x2, x1};
597 Double_t ys[] = {y1, y1, y2, y2};
599 return;
600 }
601
602 if (mode == kHollow) {
604 //
606 glRectd(x1, y1, x2, y2);
608 glLineWidth(1.f);
609 } else {
610 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE);//Set filling parameters.
611 glRectd(x1, y1, x2, y2);
612 }
613}
614
615////////////////////////////////////////////////////////////////////////////////
616///Draw tesselated polygon (probably, outline only).
617
619{
620 assert(x != nullptr && "DrawFillArea, parameter 'x' is null");
621 assert(y != nullptr && "DrawFillArea, parameter 'y' is null");
622
623 if (fLocked)
624 return;
625
626 if (n < 3) {
627 ::Error("TGLPadPainter::DrawFillArea",
628 "invalid number of points in a polygon");
629 return;
630 }
631
632 if (IsGradientFill(gVirtualX->GetFillColor()))
633 return DrawPolygonWithGradient(n, x, y);
634
635 if (!gVirtualX->GetFillStyle()) {
637 return DrawPolyLine(n, x, y);
638 }
639
641 DrawTesselation(n, x, y);
642}
643
644////////////////////////////////////////////////////////////////////////////////
645///Draw tesselated polygon (never called, probably, since TPad::PaintFillArea for floats
646///is deprecated).
647
649{
650 if (fLocked) return;
651
652 if (!gVirtualX->GetFillStyle()) {
654 return DrawPolyLine(n, x, y);
655 }
656
657 fVs.resize(n * 3);
658
659 for (Int_t i = 0; i < n; ++i) {
660 fVs[i * 3] = x[i];
661 fVs[i * 3 + 1] = y[i];
662 }
663
665
669
670 for (Int_t i = 0; i < n; ++i)
671 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
672
673
674 gluEndPolygon(t);
675}
676
677////////////////////////////////////////////////////////////////////////////////
678///Draw poly-line in user coordinates.
679
681{
682 if (fLocked) return;
683
685
686 glBegin(GL_LINE_STRIP);
687
688 for (Int_t i = 0; i < n; ++i)
689 glVertex2d(x[i], y[i]);
690
691 if (fIsHollowArea) {
692 glVertex2d(x[0], y[0]);
694 }
695 glEnd();
696
697 if (gVirtualX->GetLineWidth() > lineWidthTS) {
698 Double_t pointSize = gVirtualX->GetLineWidth();
704 glBegin(GL_POINTS);
705
706 for (Int_t i = 0; i < n; ++i)
707 glVertex2d(x[i], y[i]);
708
709 glEnd();
710 glPointSize(1.f);
711 }
712}
713
714////////////////////////////////////////////////////////////////////////////////
715///Never called?
716
718{
719 if (fLocked) return;
720
722
723 glBegin(GL_LINE_STRIP);
724
725 for (Int_t i = 0; i < n; ++i)
726 glVertex2f(x[i], y[i]);
727
728 if (fIsHollowArea) {
729 glVertex2f(x[0], y[0]);
731 }
732
733 glEnd();
734}
735
736////////////////////////////////////////////////////////////////////////////////
737///Poly line in NDC.
738
740{
741 if (fLocked) return;
742
744 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
745 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
746 const Double_t x1 = gPad->GetX1(), y1 = gPad->GetY1();
747
748 glBegin(GL_LINE_STRIP);
749
750 for (Int_t i = 0; i < n; ++i)
751 glVertex2d(x1 + u[i] * xRange, y1 + v[i] * yRange);
752
753 glEnd();
754}
755
756namespace {
757
758//Aux. function.
759template<class ValueType>
760void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst);
761
762}
763
764////////////////////////////////////////////////////////////////////////////////
765///Poly-marker.
766
768{
769 if (fLocked) return;
770
773}
774
775////////////////////////////////////////////////////////////////////////////////
776///Poly-marker.
777
779{
780 if (fLocked) return;
781
784}
785
786////////////////////////////////////////////////////////////////////////////////
787///Poly-marker.
788
790{
791 if (fLocked) return;
792
795 //
796 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
797 //
799 //
801
802 Float_t rgba[4] = {};
803 Rgl::Pad::ExtractRGBA(gVirtualX->GetMarkerColor(), rgba);
806
807 const Width_t w = TMath::Max(1, Int_t(TAttMarker::GetMarkerLineWidth(gVirtualX->GetMarkerStyle())));
809
810 const TPoint *xy = &fPoly[0];
812 const UInt_t n = UInt_t(fPoly.size());
813 switch (markerStyle) {
814 case kDot:
816 break;
817 case kPlus:
819 break;
820 case kStar:
821 case 31:
823 break;
824 case kCircle:
825 case kOpenCircle:
827 break;
828 case kMultiply:
829 fMarker.DrawX(n, xy);
830 break;
831 case kFullDotSmall://"Full dot small"
833 break;
834 case kFullDotMedium:
836 break;
837 case kFullDotLarge:
838 case kFullCircle:
840 break;
841 case kFullSquare:
843 break;
844 case kFullTriangleUp:
846 break;
849 break;
850 case kOpenSquare:
854 break;
855 case kOpenTriangleUp:
859 break;
860 case kOpenDiamond:
862 break;
863 case kOpenCross:
865 break;
866 case kFullStar:
868 break;
869 case kOpenStar:
871 break;
874 break;
875 case kFullDiamond:
877 break;
878 case kFullCross:
880 break;
883 break;
886 break;
889 break;
890 case kOctagonCross:
892 break;
895 break;
898 break;
901 break;
904 break;
907 break;
910 break;
913 break;
914 case kOpenCrossX:
916 break;
917 case kFullCrossX:
919 break;
920 case kFourSquaresX:
922 break;
923 case kFourSquaresPlus:
925 break;
926 }
927
930 glLineWidth(1.f);
931}
932
933////////////////////////////////////////////////////////////////////////////////
934
935template<class Char>
937{
939
941 //
942 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
943 //
945
946 Float_t rgba[4] = {};
947 Rgl::Pad::ExtractRGBA(gVirtualX->GetTextColor(), rgba);
949
950 //10 is the first valid font index.
951 //20 is FreeSerifBold, as in TTF.cxx and in TGLFontManager.cxx.
952 //shift - is the shift to access "extended" fonts.
954
955 Int_t fontIndex = TMath::Max(Short_t(10), gVirtualX->GetTextFont());
956 if (fontIndex / 10 + shift > TGLFontManager::GetFontFileArray()->GetEntries())
957 fontIndex = 20 + shift * 10;
958 else
959 fontIndex += shift * 10;
960
961 fFM.RegisterFont(TMath::Max(Int_t(gVirtualX->GetTextSize()) - 1, 10),//kTexture does not work if size < 10.
964 fF.PreRender();
965
966 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
967 fF.Render(text, gPad->XtoPixel(x), padH - gPad->YtoPixel(y), GetTextAngle(), GetTextMagnitude());
968
969 fF.PostRender();
971
973}
974
975////////////////////////////////////////////////////////////////////////////////
976///Draw text. This operation is especially
977///dangerous if in locked state -
978///ftgl will assert on zero texture size
979///(which is result of bad GL context).
980
982{
983 if (fLocked) return;
984
985 if (!gVirtualX->GetTextSize())
986 return;
987
989}
990
991////////////////////////////////////////////////////////////////////////////////
992///Draw text. This operation is especially
993///dangerous if in locked state -
994///ftgl will assert on zero texture size
995///(which is result of bad GL context).
996
998{
999 if (fLocked) return;
1000
1001 if (!gVirtualX->GetTextSize())
1002 return;
1003
1005}
1006
1007////////////////////////////////////////////////////////////////////////////////
1008///Draw text in NDC. This operation is especially
1009///dangerous if in locked state -
1010///ftgl will assert on zero texture size
1011///(which is result of bad GL context).
1012
1014{
1015 if (fLocked) return;
1016
1017 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
1018 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
1019 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
1020}
1021
1022////////////////////////////////////////////////////////////////////////////////
1023///Draw text in NDC. This operation is especially
1024///dangerous if in locked state -
1025///ftgl will assert on zero texture size
1026///(which is result of bad GL context).
1027
1029{
1030 if (fLocked) return;
1031
1032 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
1033 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
1034 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
1035}
1036
1037////////////////////////////////////////////////////////////////////////////////
1038///Save the projection matrix.
1039///Attention! GL_PROJECTION will become the current matrix
1040///after this call!
1041
1047
1048////////////////////////////////////////////////////////////////////////////////
1049///Restore the projection matrix.
1050///Attention! GL_PROJECTION will become the current matrix
1051///after this call!
1052
1058
1059////////////////////////////////////////////////////////////////////////////////
1060///Save the modelview matrix.
1061///Attention! GL_MODELVIEW will become the current matrix
1062///after this call!
1063
1069
1070////////////////////////////////////////////////////////////////////////////////
1071///Restore the modelview matrix.
1072///Attention! GL_MODELVIEW will become the current matrix
1073///after this call!
1074
1080
1081////////////////////////////////////////////////////////////////////////////////
1082///Extract and save the current viewport.
1083
1088
1089////////////////////////////////////////////////////////////////////////////////
1090///Restore the saved viewport.
1091
1093{
1094 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
1095}
1096
1097////////////////////////////////////////////////////////////////////////////////
1098/// Using TImage save frame-buffer contents as a picture.
1099
1100void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
1101{
1102 auto canvas = pad->GetCanvas();
1103 if (!canvas)
1104 return;
1105
1106 canvas->Flush();
1107
1108 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
1111 //In case GL_BGRA is not in gl.h (old windows' gl) - comment/uncomment lines.
1112 //glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_BGRA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
1113 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
1114
1115 std::unique_ptr<TImage> image(TImage::Create());
1116 if (!image.get()) {
1117 ::Error("TGLPadPainter::SaveImage", "TImage creation failed");
1118 return;
1119 }
1120
1121 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
1122 UInt_t *argb = image->GetArgbArray();
1123
1124 if (!argb) {
1125 ::Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
1126 return;
1127 }
1128
1129 const Int_t nLines = canvas->GetWh();
1130 const Int_t nPixels = canvas->GetWw();
1131
1132 for (Int_t i = 0; i < nLines; ++i) {
1133 Int_t base = (nLines - 1 - i) * nPixels;
1134 for (Int_t j = 0; j < nPixels; ++j, ++base) {
1135 //Uncomment/comment if you don't have GL_BGRA.
1136
1137 const UInt_t pix = buff[base];
1138 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
1139 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
1140
1141 //argb[i * nPixels + j] = buff[base];
1142 argb[i * nPixels + j] = bgra;
1143 }
1144 }
1145
1146 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
1147}
1148
1149////////////////////////////////////////////////////////////////////////////////
1150
1153{
1154 if (fLocked)
1155 return;
1156
1157 if (!pixelData) {
1158 //I'd prefer an assert.
1159 ::Error("TGLPadPainter::DrawPixels", "pixel data is null");
1160 return;
1161 }
1162
1163 if (std::numeric_limits<UInt_t>::digits >= 32) {
1164 //TASImage uses bit 31 as ...
1165 //alpha channel flag! FUUUUUUUUUUUUU ..... !!!
1166 CLRBIT(width, 31);
1167 CLRBIT(height, 31);
1168 }
1169
1170 if (!width) {
1171 //Assert is better.
1172 ::Error("TGLPadPainter::DrawPixels", "invalid width");
1173 return;
1174 }
1175
1176 if (!height) {
1177 //Assert is better.
1178 ::Error("TGLPadPainter::DrawPixels", "invalid height");
1179 return;
1180 }
1181
1182 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
1183 //TASImage passes pixel coordinates in pad's pixmap coordinate space.
1184 //While glRasterPosX said to work with 'window' coordinates,
1185 //that's a lie :) it does not :)
1186
1187 const Double_t rasterX = Double_t(dstX) / (pad->GetAbsWNDC() * pad->GetWw()) *
1188 (pad->GetX2() - pad->GetX1()) + pad->GetX1();
1189
1190 const Double_t yRange = pad->GetY2() - pad->GetY1();
1191 const Double_t rasterY = yRange - Double_t(dstY + height) / (pad->GetAbsHNDC() * pad->GetWh()) * yRange +
1192 pad->GetY1();
1193
1194 GLdouble oldPos[4] = {};
1195 //Save the previous raster pos.
1197
1199 //Stupid asimage provides us upside-down image.
1200 std::vector<unsigned char> upsideDownImage(4 * width * height);
1201 const unsigned char *srcLine = pixelData + 4 * width * (height - 1);
1202 unsigned char *dstLine = &upsideDownImage[0];
1203 for (UInt_t i = 0; i < height; ++i, srcLine -= 4 * width, dstLine += 4 * width)
1204 std::copy(srcLine, srcLine + 4 * width, dstLine);
1205
1206 if (enableBlending) {
1209 }
1210
1212
1213 if (enableBlending)
1215
1216 //Restore raster pos.
1217 glRasterPos2d(oldPos[0], oldPos[1]);
1218 } else
1219 ::Error("TGLPadPainter::DrawPixels", "no pad found to draw");
1220}
1221
1222//Aux. functions - gradient and solid fill of arbitrary area.
1223
1224////////////////////////////////////////////////////////////////////////////////
1225///At the moment I assume both linear and radial gradients will work the same way -
1226///using a stencil buffer and some big rectangle(s) to fill with a gradient.
1227///Thus I have a 'common' part - the part responsible for a stencil test.
1228
1230{
1231 assert(n > 2 && "DrawPolygonWithGradient, invalid number of points");
1232 assert(x != nullptr && "DrawPolygonWithGradient, parameter 'x' is null");
1233 assert(y != nullptr && "DrawPolygonWithGradient, parameter 'y' is null");
1234
1235 assert(dynamic_cast<TColorGradient *>(gROOT->GetColor(gVirtualX->GetFillColor())) != nullptr &&
1236 "DrawPolygonWithGradient, the current fill color is not a gradient fill");
1237 const TColorGradient * const grad =
1238 dynamic_cast<TColorGradient *>(gROOT->GetColor(gVirtualX->GetFillColor()));
1239
1240 if (fLocked)
1241 return;
1242
1243 //Now, some magic!
1245
1246 //TODO: check that the state is restored back correctly after
1247 // we done with a gradient.
1248 //TODO: make sure that we have glDepthMask set to false in general!
1250
1251 glStencilFunc(GL_NEVER, 1, 0xFF);
1252 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);// draw 1s on test fail (always)
1253 //Draw stencil pattern
1254 glStencilMask(0xFF);
1256
1257 //Draw our polygon into the stencil buffer:
1258 DrawTesselation(n, x, y);
1259
1261 glStencilMask(0x00);
1262 //Draw where stencil's value is 0
1263 glStencilFunc(GL_EQUAL, 0, 0xFF);
1264 //Draw only where stencil's value is 1
1265 glStencilFunc(GL_EQUAL, 1, 0xFF);
1266
1267 //At the moment radial gradient is derived from linear - it was convenient
1268 //at some point, but in fact it was a bad idea. And now I have to
1269 //first check radial gradient.
1270 //TODO: TRadialGradient must inherit TColorGradient directly.
1271 const TRadialGradient * const rGrad = dynamic_cast<const TRadialGradient *>(grad);
1272 if (rGrad)
1273 DrawGradient(rGrad, n, x, y);
1274 else {
1275 const TLinearGradient * const lGrad = dynamic_cast<const TLinearGradient *>(grad);
1276 assert(lGrad != nullptr && "DrawPolygonWithGradient, unknown gradient type");
1277 DrawGradient(lGrad, n, x, y);
1278 }
1279}
1280
1281////////////////////////////////////////////////////////////////////////////////
1282
1284 const Double_t *xs, const Double_t *ys)
1285{
1286 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1287 assert(nPoints > 2 && "DrawGradient, invalid number of points");
1288 assert(xs != nullptr && "DrawGradient, parameter 'xs' is null");
1289 assert(ys != nullptr && "DrawGradient, parameter 'ys' is null");
1290
1292 ::Warning("TGLPadPainter::DrawGradient",
1293 "extended radial gradient is not supported");//yet?
1294 return;
1295 }
1296
1297 //TODO: check the polygon's bbox!
1298 const auto &bbox = Rgl::Pad::FindBoundingRect(nPoints, xs, ys);
1299 //
1300 auto center = grad->GetCenter();
1301 auto radius = grad->GetRadius();
1302 //Adjust the center and radius depending on coordinate mode.
1304 radius *= TMath::Max(bbox.fWidth, bbox.fHeight);
1305 center.fX = bbox.fWidth * center.fX + bbox.fXMin;
1306 center.fY = bbox.fHeight * center.fY + bbox.fYMin;
1307 } else {
1308 const auto w = gPad->GetX2() - gPad->GetX1();
1309 const auto h = gPad->GetY2() - gPad->GetY1();
1310
1311 radius *= TMath::Max(w, h);
1312 center.fX *= w;
1313 center.fY *= h;
1314 }
1315 //Now for the gradient fill we switch into pixel coordinates:
1316 const auto pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1317 const auto pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1318 //
1321 //A new ortho projection:
1324 //
1325 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1326 //
1328 center.fX = gPad->XtoPixel(center.fX);
1329 center.fY = pixelH - gPad->YtoPixel(center.fY);
1330
1331 Double_t maxR = 0.;
1332 {
1333 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1334 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1335 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1336 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1337 //Get the longest distance from the center to the bounding box vertices
1338 //(this will be the maximum possible radius):
1339 const Double_t maxDistX = TMath::Max(TMath::Abs(center.fX - xMin),
1340 TMath::Abs(center.fX - xMax));
1341 const Double_t maxDistY = TMath::Max(TMath::Abs(center.fY - yMin),
1342 TMath::Abs(center.fY - yMax));
1344 }
1345
1346 //If gradient 'stops inside the polygon', we use
1347 //the solid fill for the area outside of radial gradient:
1348 const Bool_t solidFillAfter = maxR > radius;
1349 //We emulate a radial gradient using triangles and linear gradient:
1350 //TODO: Can be something smarter? (btw even 100 seems to be enough)
1351 const UInt_t nSlices = 500;
1352
1353 const auto nColors = grad->GetNumberOfSteps();
1354 //+1 - the strip from the last color's position to radius,
1355 //and (probably) + 1 for solidFillAfter.
1356 const auto nCircles = nColors + 1 + solidFillAfter;
1357
1358 //TODO: can locations be outside of [0., 1.] ???
1359 //at the moment I assume the answer is NO, NEVER.
1360 const auto locations = grad->GetColorPositions();
1361 // * 2 below == x,y
1362 std::vector<Double_t> circles(nSlices * nCircles * 2);
1363 const Double_t angle = TMath::TwoPi() / nSlices;
1364
1365 //"Main" circles (for colors at locations[i]).
1366 for (UInt_t i = 0; i < nColors; ++i) {
1367 const auto circle = &circles[i * nSlices * 2];
1368 //TODO: either check locations here or somewhere else.
1369 const auto r = radius * locations[i];
1370 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1371 circle[j] = center.fX + r * TMath::Cos(angle * j);
1372 circle[j + 1] = center.fY + r * TMath::Sin(angle * j);
1373 }
1374 //The "closing" vertices:
1375 circle[(nSlices - 1) * 2] = circle[0];
1376 circle[(nSlices - 1) * 2 + 1] = circle[1];
1377 }
1378
1379 {
1380 //The strip between lastPos and radius:
1381 const auto circle = &circles[nColors * nSlices * 2];
1382 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1383 circle[j] = center.fX + radius * TMath::Cos(angle * j);
1384 circle[j + 1] = center.fY + radius * TMath::Sin(angle * j);
1385 }
1386
1387 circle[(nSlices - 1) * 2] = circle[0];
1388 circle[(nSlices - 1) * 2 + 1] = circle[1];
1389 }
1390
1391 if (solidFillAfter) {
1392 //The strip after the radius:
1393 const auto circle = &circles[(nCircles - 1) * nSlices * 2];
1394 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1395 circle[j] = center.fX + maxR * TMath::Cos(angle * j);
1396 circle[j + 1] = center.fY + maxR * TMath::Sin(angle * j);
1397 }
1398
1399 circle[(nSlices - 1) * 2] = circle[0];
1400 circle[(nSlices - 1) * 2 + 1] = circle[1];
1401 }
1402
1403 //Now we draw:
1404 //1) triangle fan in the center (from center to the locations[1],
1405 // with a solid fill).
1406 //2) quad strips for colors.
1407 //3) additional quad strip from the lastLocation to the radius
1408 //4) additional quad strip (if any) from the radius to maxR.
1409
1410 //RGBA values:
1411 const auto rgba = grad->GetColors();
1412
1414 //TODO?
1416
1417 //Probably a degenerated case. Maybe not.
1420 glVertex2d(center.fX, center.fY);
1421
1422 for (UInt_t i = 0, e = nSlices * 2; i < e; i += 2)
1423 glVertex2dv(&circles[i]);
1424
1425 glEnd();
1426
1427 //No auto for circles, explicit types to have const Double_t * const, not Duble_t * const.
1428 for (UInt_t i = 0; i < nColors - 1; ++i) {
1429 const Double_t * const inner = &circles[i * nSlices * 2];
1430 const auto innerRGBA = rgba + i * 4;
1431 const auto outerRGBA = rgba + (i + 1) * 4;
1432 const Double_t * const outer = &circles[(i + 1) * nSlices * 2];
1433
1435 }
1436
1437 //Probably degenerated strip.
1438 {
1439 const Double_t * const inner = &circles[nSlices * (nColors - 1) * 2];
1440 const auto solidRGBA = rgba + (nColors - 1) * 4;
1441 const Double_t * const outer = &circles[nSlices * nColors * 2];
1442
1444 }
1445
1446 if (solidFillAfter) {
1447 const Double_t * const inner = &circles[nSlices * nColors * 2];
1448 const auto solidRGBA = rgba + (nColors - 1) * 4;
1449 const Double_t * const outer = &circles[nSlices * (nColors + 1) * 2];
1450
1452 }
1453
1456}
1457
1458////////////////////////////////////////////////////////////////////////////////
1459
1461 const Double_t *x, const Double_t *y)
1462{
1463 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1464 assert(n > 2 && "DrawGradient, invalid number of points");
1465 assert(x != nullptr && "DrawGradient, parameter 'x' is null");
1466 assert(y != nullptr && "DrawGradient, parameter 'y' is null");
1467
1468 //Now we fill the whole scene with one big rectangle
1469 //(group of rectangles) with a gradient fill using
1470 //stencil test.
1471
1472 //Find a bounding rect.
1473 const auto &bbox = Rgl::Pad::FindBoundingRect(n, x, y);
1474 //TODO: check the bbox??
1475
1476 //For the gradient fill we switch into the
1477 //pixel coordinates.
1480
1481 //A new ortho projection:
1484
1485 const Double_t pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1486 const Double_t pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1487 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1488
1489 //A new modelview:
1492 //
1493 TColorGradient::Point start = grad->GetStart();
1494 TColorGradient::Point end = grad->GetEnd();
1495
1496 //Change gradient coordinates from 'NDC' to pad coords:
1498 {
1499 const Double_t w = gPad->GetX2() - gPad->GetX1();
1500 const Double_t h = gPad->GetY2() - gPad->GetY1();
1501
1502 start.fX = start.fX * w;
1503 start.fY = start.fY * h;
1504 end.fX = end.fX * w;
1505 end.fY = end.fY * h;
1506 } else {
1507 start.fX = start.fX * bbox.fWidth + bbox.fXMin;
1508 start.fY = start.fY * bbox.fHeight + bbox.fYMin;
1509 end.fX = end.fX * bbox.fWidth + bbox.fXMin;
1510 end.fY = end.fY * bbox.fHeight + bbox.fYMin;
1511 }
1512
1513 //TODO: with a radial fill we'll have to extract the code
1514 // below into the separate function/and have additional function
1515 // for a radial gradient.
1516 //Now from pad to pixels:
1517 start.fX = gPad->XtoPixel(start.fX);
1518 start.fY = pixelH - gPad->YtoPixel(start.fY);
1519 end.fX = gPad->XtoPixel(end.fX);
1520 end.fY = pixelH - gPad->YtoPixel(end.fY);
1521 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1522 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1523 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1524 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1525 //
1526
1527 //TODO: check all calculations!
1528
1529 //Get the longest distance from the start point to the bounding box vertices:
1530 const Double_t maxDistX = TMath::Max(TMath::Abs(start.fX - xMin), TMath::Abs(start.fX - xMax));
1531 const Double_t maxDistY = TMath::Max(TMath::Abs(start.fY - yMin), TMath::Abs(start.fY - yMax));
1532
1533 const Double_t startEndLength = TMath::Sqrt((end.fX - start.fX) * (end.fX - start.fX) +
1534 (end.fY - start.fY) * (end.fY - start.fY));
1537
1538 //Boxes with a gradients to emulate gradient fill with many colors:
1539 const Double_t * const colorPositions = grad->GetColorPositions();
1540 std::vector<Double_t> gradBoxes(grad->GetNumberOfSteps() + 2);
1541 gradBoxes[0] = start.fY - h;
1542 for (unsigned i = 1; i <= grad->GetNumberOfSteps(); ++i)
1543 gradBoxes[i] = startEndLength * colorPositions[i - 1] + start.fY;
1544
1545 gradBoxes[grad->GetNumberOfSteps() + 1] = start.fY + h;
1546
1547 //Rotation angle - gradient's axis:
1548 Double_t angle = TMath::ACos((startEndLength * (end.fY - start.fY)) /
1550 if (end.fX > start.fX)
1551 angle *= -1;
1552
1553 glTranslated(start.fX, start.fY, 0.);
1554 glRotated(angle, 0., 0., 1.);
1555 glTranslated(-start.fX, -start.fY, 0.);
1556 //
1557 const Double_t * const rgba = grad->GetColors();
1558
1559 const unsigned nEdges = gradBoxes.size();
1560 const unsigned nColors = grad->GetNumberOfSteps();
1561 const Double_t xLeft = start.fX - h, xRight = start.fX + h;
1562
1564 //TODO?
1566
1569 rgba + (nColors - 1) * 4, rgba + (nColors - 1) * 4);
1570
1571 for (unsigned i = 1; i < nEdges - 2; ++i)
1573 xRight, rgba + (i - 1) * 4, rgba + i * 4);
1574
1577}
1578
1579////////////////////////////////////////////////////////////////////////////////
1580
1582{
1583 assert(n > 2 && "DrawTesselation, invalid number of points");
1584 assert(x != nullptr && "DrawTesselation, parameter 'x' is null");
1585 assert(y != nullptr && "DrawTesselation, parameter 'y' is null");
1586
1587 //Data for a tesselator:
1588 fVs.resize(n * 3);
1589
1590 for (Int_t i = 0; i < n; ++i) {
1591 fVs[i * 3] = x[i];
1592 fVs[i * 3 + 1] = y[i];
1593 fVs[i * 3 + 2] = 0.;
1594 }
1595
1596 //TODO: A very primitive way to tesselate - check what
1597 //kind of polygons we can really have from TPad/TCanvas.
1599 gluBeginPolygon(t);
1601
1602 for (Int_t i = 0; i < n; ++i)
1603 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
1604
1605 gluEndPolygon(t);
1606}
1607
1608
1609//Aux. functions.
1610namespace {
1611
1612template<class ValueType>
1613void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst)
1614{
1615 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
1616
1617 dst.resize(n);
1618 for (Int_t i = 0; i < n; ++i) {
1619 dst[i].fX = gPad->XtoPixel(x[i]);
1620 dst[i].fY = padH - gPad->YtoPixel(y[i]);
1621 }
1622}
1623
1624}
1625
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
short Style_t
Style number (short)
Definition RtypesCore.h:96
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
float Size_t
Attribute size (float)
Definition RtypesCore.h:103
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
short Width_t
Line width (short)
Definition RtypesCore.h:98
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
short Font_t
Font number (short)
Definition RtypesCore.h:95
short Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
#define CLRBIT(n, i)
Definition Rtypes.h:93
@ kOpenDoubleDiamond
Definition TAttMarker.h:68
@ kStar
Definition TAttMarker.h:58
@ kFullDotLarge
Definition TAttMarker.h:59
@ kFullDoubleDiamond
Definition TAttMarker.h:68
@ kOpenFourTrianglesX
Definition TAttMarker.h:67
@ kOpenSquare
Definition TAttMarker.h:61
@ kFullThreeTriangles
Definition TAttMarker.h:66
@ kOpenTriangleUp
Definition TAttMarker.h:62
@ kFourSquaresPlus
Definition TAttMarker.h:71
@ kFullDotSmall
Definition TAttMarker.h:59
@ kFullDotMedium
Definition TAttMarker.h:59
@ kOpenTriangleDown
Definition TAttMarker.h:63
@ kOpenThreeTriangles
Definition TAttMarker.h:65
@ kFullCrossX
Definition TAttMarker.h:70
@ kFullFourTrianglesX
Definition TAttMarker.h:67
@ kFullTriangleDown
Definition TAttMarker.h:61
@ kCircle
Definition TAttMarker.h:58
@ kOpenCrossX
Definition TAttMarker.h:70
@ kFullFourTrianglesPlus
Definition TAttMarker.h:69
@ kFullSquare
Definition TAttMarker.h:60
@ kOpenSquareDiagonal
Definition TAttMarker.h:65
@ kFullStar
Definition TAttMarker.h:63
@ kOpenDiamond
Definition TAttMarker.h:62
@ kFullTriangleUp
Definition TAttMarker.h:60
@ kOpenDiamondCross
Definition TAttMarker.h:64
@ kOpenFourTrianglesPlus
Definition TAttMarker.h:69
@ kMultiply
Definition TAttMarker.h:58
@ kPlus
Definition TAttMarker.h:58
@ kOctagonCross
Definition TAttMarker.h:66
@ kFullCircle
Definition TAttMarker.h:60
@ kDot
Definition TAttMarker.h:58
@ kOpenCross
Definition TAttMarker.h:62
@ kFourSquaresX
Definition TAttMarker.h:70
@ kOpenCircle
Definition TAttMarker.h:61
@ kFullCross
Definition TAttMarker.h:64
@ kOpenStar
Definition TAttMarker.h:63
@ kFullDiamond
Definition TAttMarker.h:64
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
const Double_t lineWidthTS
#define GL_BGRA
Definition TGLViewer.cxx:61
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void pix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint xy
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t width
Option_t Option_t TPoint TPoint percent
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint DrawText
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
Option_t Option_t TPoint TPoint const char text
Option_t Option_t TPoint TPoint const char y1
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:627
#define gROOT
Definition TROOT.h:414
#define gPad
#define gVirtualX
Definition TVirtualX.h:365
Double_t GetMaxLineWidth() const
Double_t GetMaxPointSize() const
void DrawOpenThreeTriangles(UInt_t n, const TPoint *xy) const
void DrawFullCrossX(UInt_t n, const TPoint *xy) const
void DrawFullDotSmall(UInt_t n, const TPoint *xy) const
void DrawOpenSquareDiagonal(UInt_t n, const TPoint *xy) const
void DrawOpenDoubleDiamond(UInt_t n, const TPoint *xy) const
void DrawFullFourTrianglesX(UInt_t n, const TPoint *xy) const
void DrawFullDotLarge(UInt_t n, const TPoint *xy) const
void DrawFullThreeTriangles(UInt_t n, const TPoint *xy) const
void DrawCircle(UInt_t n, const TPoint *xy) const
void DrawFullFourTrianglesPlus(UInt_t n, const TPoint *xy) const
void DrawOpenCross(UInt_t n, const TPoint *xy) const
void DrawFullCross(UInt_t n, const TPoint *xy) const
void DrawFullTrianlgeDown(UInt_t n, const TPoint *xy) const
void DrawOpenStar(UInt_t n, const TPoint *xy) const
Full star pentagone.
void DrawX(UInt_t n, const TPoint *xy) const
void DrawPlus(UInt_t n, const TPoint *xy) const
void DrawFullTrianlgeUp(UInt_t n, const TPoint *xy) const
void DrawFullSquare(UInt_t n, const TPoint *xy) const
void DrawOpenFourTrianglesPlus(UInt_t n, const TPoint *xy) const
void DrawStar(UInt_t n, const TPoint *xy) const
void DrawFullDoubleDiamond(UInt_t n, const TPoint *xy) const
void DrawOpenCrossX(UInt_t n, const TPoint *xy) const
void DrawDot(UInt_t n, const TPoint *xy) const
Simple 1-pixel dots.
void DrawOctagonCross(UInt_t n, const TPoint *xy) const
void DrawFourSquaresX(UInt_t n, const TPoint *xy) const
void DrawFourSquaresPlus(UInt_t n, const TPoint *xy) const
void DrawFullDotMedium(UInt_t n, const TPoint *xy) const
void DrawDiamond(UInt_t n, const TPoint *xy) const
void DrawFullStar(UInt_t n, const TPoint *xy) const
Full star pentagone.
void DrawOpenTrianlgeDown(UInt_t n, const TPoint *xy) const
void DrawFullDiamond(UInt_t n, const TPoint *xy) const
void DrawOpenFourTrianglesX(UInt_t n, const TPoint *xy) const
void DrawOpenDiamondCross(UInt_t n, const TPoint *xy) const
void * GetTess() const
static Width_t GetMarkerLineWidth(Style_t style)
Internal helper function that returns the line width of the given marker style (0 = filled marker)
static Style_t GetMarkerStyleBase(Style_t style)
Internal helper function that returns the corresponding marker style with line width 1 for the given ...
TColorGradient extends basic TColor.
const Double_t * GetColors() const
Get colors.
SizeType_t GetNumberOfSteps() const
Get number of steps.
ECoordinateMode GetCoordinateMode() const
Get coordinate mode.
const Double_t * GetColorPositions() const
Get color positions.
void RegisterFont(Int_t size, Int_t file, TGLFont::EMode mode, TGLFont &out)
Provide font with given size, file and FTGL class.
static Int_t GetExtendedFontStartIndex()
static const char * GetFontNameFromId(Int_t)
Get font name from TAttAxis font id.
static TObjArray * GetFontFileArray()
Get id to file name map.
void Render(const char *txt, Double_t x, Double_t y, Double_t angle, Double_t mgn) const
virtual void PostRender() const
Reset GL state after FTFont rendering.
virtual void PreRender(Bool_t autoLight=kTRUE, Bool_t lightOn=kFALSE) const
Set-up GL state before FTFont rendering.
void DrawText(Double_t x, Double_t y, const char *text, ETextMode mode) override
Draw text.
void SetLineColor(Color_t lcolor) override
Delegate to gVirtualX.
void SetDrawMode(Int_t device, Int_t mode) override
Set drawing mode for specified device.
void DrawPixels(const unsigned char *pixelData, UInt_t width, UInt_t height, Int_t dstX, Int_t dstY, Bool_t enableBlending) override
Float_t GetTextSize() const override
Delegate to gVirtualX.
Int_t ResizeDrawable(Int_t device, UInt_t w, UInt_t h) override
Resize a gVirtualX Pixmap.
void DestroyDrawable(Int_t device) override
Not required at the moment.
void DrawGradient(const TLinearGradient *gradient, Int_t n, const Double_t *x, const Double_t *y)
Rgl::Pad::Tesselator fTess
Float_t GetTextAngle() const override
Delegate to gVirtualX.
void DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2) override
Draw line segment in NDC coordinates.
Style_t GetLineStyle() const override
Delegate to gVirtualX.
WinContext_t fWinContext
Color_t GetTextColor() const override
Delegate to gVirtualX.
std::vector< TPoint > fPoly
void DrawTextHelper(Double_t x, Double_t y, const Char_t *text, ETextMode mode)
void DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EBoxMode mode) override
Draw filled or hollow box.
void SetFillColor(Color_t fcolor) override
Delegate to gVirtualX.
Color_t GetMarkerColor() const override
Delegate to gVirtualX.
void SetTextSizePixels(Int_t npixels) override
Delegate to gVirtualX.
void SetTextFont(Font_t tfont) override
Delegate to gVirtualX.
void DrawPolygonWithGradient(Int_t n, const Double_t *x, const Double_t *y)
At the moment I assume both linear and radial gradients will work the same way - using a stencil buff...
void InvalidateCS() override
When TPad::Range for gPad is called, projection must be changed in OpenGL.
void ClearDrawable() override
Call gVirtualX->ClearWindow()
Color_t GetLineColor() const override
Delegate to gVirtualX.
void DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v) override
Poly line in NDC.
void DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y) override
Draw poly-line in user coordinates.
void SetTextAlign(Short_t align) override
Delegate to gVirtualX.
Rgl::Pad::GLLimits fLimits
void SetOpacity(Int_t percent) override
Delegate to gVirtualX.
void SetTextAngle(Float_t tangle) override
Delegate to gVirtualX.
void DrawTextNDC(Double_t x, Double_t y, const char *text, ETextMode mode) override
Draw text in NDC.
void SetTextColor(Color_t tcolor) override
Delegate to gVirtualX.
void SetMarkerSize(Size_t msize) override
Delegate to gVirtualX.
void InitPainter() override
Init gl-pad painter:
void SelectDrawable(Int_t device) override
For gVirtualX this means select pixmap (or window) and all subsequent drawings will go into this pixm...
TGLFontManager fFM
Rgl::Pad::PolygonStippleSet fSSet
Rgl::Pad::MarkerPainter fMarker
void DrawPolyMarker()
Poly-marker.
void SaveViewport()
Extract and save the current viewport.
void SetLineWidth(Width_t lwidth) override
Delegate to gVirtualX.
void CopyDrawable(Int_t device, Int_t px, Int_t py) override
Not required at the moment.
void SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const override
Using TImage save frame-buffer contents as a picture.
Style_t GetMarkerStyle() const override
Delegate to gVirtualX.
void SetTextSize(Float_t tsize) override
Delegate to gVirtualX.
void DrawFillArea(Int_t n, const Double_t *x, const Double_t *y) override
Draw tesselated polygon (probably, outline only).
Short_t GetTextAlign() const override
Delegate to gVirtualX.
void SetMarkerStyle(Style_t mstyle) override
Delegate to gVirtualX.
Style_t GetFillStyle() const override
Delegate to gVirtualX.
void SetFillStyle(Style_t fstyle) override
Delegate to gVirtualX.
void UpdateDrawable(Int_t mode) override
Call low-level update of selected drawable, redirect to gVirtualX.
Font_t GetTextFont() const override
Delegate to gVirtualX.
void RestoreProjectionMatrix() const
Restore the projection matrix.
void SetLineStyle(Style_t lstyle) override
Delegate to gVirtualX.
void LockPainter() override
Locked state of painter means, that GL context can be invalid, so no GL calls can be executed.
Float_t GetTextMagnitude() const override
Delegate to gVirtualX.
Width_t GetLineWidth() const override
Delegate to gVirtualX.
void DrawTesselation(Int_t n, const Double_t *x, const Double_t *y)
Color_t GetFillColor() const override
Delegate to gVirtualX.
Int_t CreateDrawable(UInt_t w, UInt_t h) override
Not required at the moment.
Bool_t IsTransparent() const override
Delegate to gVirtualX.
Size_t GetMarkerSize() const override
Delegate to gVirtualX.
void RestoreModelviewMatrix() const
Restore the modelview matrix.
std::vector< Double_t > fVs
Bool_t fIsHollowArea
void SaveProjectionMatrix() const
Save the projection matrix.
void DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2) override
Draw line segment.
Bool_t IsCocoa() const override
Returns true when cocoa backend is used.
void SetMarkerColor(Color_t mcolor) override
Delegate to gVirtualX.
void SaveModelviewMatrix() const
Save the modelview matrix.
void RestoreViewport()
Restore the saved viewport.
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition TGLUtil.cxx:1573
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition TGLUtil.cxx:1843
EImageFileTypes
Definition TImage.h:36
static TImage * Create()
Create an image.
Definition TImage.cxx:34
const Point & GetEnd() const
Get end.
const Point & GetStart() const
Get start.
The most important graphics class in the ROOT system.
Definition TPad.h:28
Double_t GetRadius() const
Get radius.
const Point & GetCenter() const
Get center.
EGradientType GetGradientType() const
Get gradient type.
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
BoundingRect< ValueType > FindBoundingRect(Int_t nPoints, const ValueType *xs, const ValueType *ys)
void ExtractRGBA(Color_t colorIndex, Float_t *rgba)
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:3216
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:3196
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Definition TMath.h:643
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:605
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:599
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition TMath.h:75
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
constexpr Double_t TwoPi()
Definition TMath.h:47