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
25#include "TColorGradient.h"
26#include "TGLPadPainter.h"
27#include "TGLIncludes.h"
28#include "TGLUtil.h"
29#include "TMath.h"
30
31#include <glad/gl.h>
32
33namespace {
34
35////////////////////////////////////////////////////////////////////////////////
36///Not a bad idea to assert on gVirtualX != nullptr
37
39{
40 return dynamic_cast<TColorGradient *>(gROOT->GetColor(fillColorIndex));
41}
42
43}
44
45/** \class TGLPadPainter
46\ingroup opengl
47"Delegating" part of TGLPadPainter. Line/fill/etc. attributes can be
48set inside TPad, but not only there:
49many of them are set by base sub-objects of 2d primitives
50(2d primitives usually inherit TAttLine or TAttFill etc.). And these sub-objects
51call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
52it will be mess - at any moment I do not know, where to take line attribute - from
53gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
54*/
55
56
57////////////////////////////////////////////////////////////////////////////////
58
60 : fIsHollowArea(kFALSE),
61 fLocked(kTRUE)
62{
63 fVp[0] = fVp[1] = fVp[2] = fVp[3] = 0;
64}
65
66
67////////////////////////////////////////////////////////////////////////////////
68///Delegate to gVirtualX.
69
71{
72 return gVirtualX->GetLineColor();
73}
74
75////////////////////////////////////////////////////////////////////////////////
76///Delegate to gVirtualX.
77
79{
80 return gVirtualX->GetLineStyle();
81}
82
83////////////////////////////////////////////////////////////////////////////////
84///Delegate to gVirtualX.
85
87{
88 return gVirtualX->GetLineWidth();
89}
90
91////////////////////////////////////////////////////////////////////////////////
92///Delegate to gVirtualX.
93
98
99////////////////////////////////////////////////////////////////////////////////
100///Delegate to gVirtualX.
101
103{
104 gVirtualX->SetLineStyle(lstyle);
105}
106
107////////////////////////////////////////////////////////////////////////////////
108///Delegate to gVirtualX.
109
111{
112 gVirtualX->SetLineWidth(lwidth);
113}
114
115////////////////////////////////////////////////////////////////////////////////
116///Delegate to gVirtualX.
117
119{
120 return gVirtualX->GetFillColor();
121}
122
123////////////////////////////////////////////////////////////////////////////////
124///Delegate to gVirtualX.
125
127{
128 return gVirtualX->GetFillStyle();
129}
130
131////////////////////////////////////////////////////////////////////////////////
132///Delegate to gVirtualX.
133///IsTransparent is implemented as inline function in TAttFill.
134
136{
137 return gVirtualX->IsTransparent();
138}
139
140////////////////////////////////////////////////////////////////////////////////
141///Delegate to gVirtualX.
142
144{
145 gVirtualX->SetFillColor(fcolor);
146}
147
148////////////////////////////////////////////////////////////////////////////////
149///Delegate to gVirtualX.
150
152{
153 gVirtualX->SetFillStyle(fstyle);
154}
155
156////////////////////////////////////////////////////////////////////////////////
157///Delegate to gVirtualX.
158
160{
161 gVirtualX->SetOpacity(percent);
162}
163
164////////////////////////////////////////////////////////////////////////////////
165///Delegate to gVirtualX.
166
168{
169 return gVirtualX->GetTextAlign();
170}
171
172////////////////////////////////////////////////////////////////////////////////
173///Delegate to gVirtualX.
174
176{
177 return gVirtualX->GetTextAngle();
178}
179
180////////////////////////////////////////////////////////////////////////////////
181///Delegate to gVirtualX.
182
184{
185 return gVirtualX->GetTextColor();
186}
187
188////////////////////////////////////////////////////////////////////////////////
189///Delegate to gVirtualX.
190
192{
193 return gVirtualX->GetTextFont();
194}
195
196////////////////////////////////////////////////////////////////////////////////
197///Delegate to gVirtualX.
198
200{
201 return gVirtualX->GetTextSize();
202}
203
204////////////////////////////////////////////////////////////////////////////////
205///Delegate to gVirtualX.
206
208{
209 return gVirtualX->GetTextMagnitude();
210}
211
212////////////////////////////////////////////////////////////////////////////////
213///Delegate to gVirtualX.
214
216{
217 gVirtualX->SetTextAlign(align);
218}
219
220////////////////////////////////////////////////////////////////////////////////
221///Delegate to gVirtualX.
222
224{
225 gVirtualX->SetTextAngle(tangle);
226}
227
228////////////////////////////////////////////////////////////////////////////////
229///Delegate to gVirtualX.
230
232{
233 gVirtualX->SetTextColor(tcolor);
234}
235
236////////////////////////////////////////////////////////////////////////////////
237///Delegate to gVirtualX.
238
240{
241 gVirtualX->SetTextFont(tfont);
242}
243
244////////////////////////////////////////////////////////////////////////////////
245///Delegate to gVirtualX.
246
248{
249 gVirtualX->SetTextSize(tsize);
250}
251
252////////////////////////////////////////////////////////////////////////////////
253///Delegate to gVirtualX.
254
256{
257 gVirtualX->SetTextSizePixels(npixels);
258}
259
260
261////////////////////////////////////////////////////////////////////////////////
262/// Delegate to gVirtualX.
263
265{
266 return gVirtualX->GetMarkerColor();
267}
268
269
270////////////////////////////////////////////////////////////////////////////////
271/// Delegate to gVirtualX.
272
274{
275 return gVirtualX->GetMarkerStyle();
276}
277
278
279////////////////////////////////////////////////////////////////////////////////
280/// Delegate to gVirtualX.
281
283{
284 return gVirtualX->GetMarkerSize();
285}
286
287
288////////////////////////////////////////////////////////////////////////////////
289/// Delegate to gVirtualX.
290
292{
293 gVirtualX->SetMarkerColor(mcolor);
294}
295
296
297////////////////////////////////////////////////////////////////////////////////
298/// Delegate to gVirtualX.
299
301{
302 gVirtualX->SetMarkerStyle(mstyle);
303}
304
305
306////////////////////////////////////////////////////////////////////////////////
307/// Delegate to gVirtualX.
308
310{
311 gVirtualX->SetMarkerSize(msize);
312}
313
314/*
315"Pixmap" part of TGLPadPainter.
316*/
317
318////////////////////////////////////////////////////////////////////////////////
319///Not required at the moment.
320
322{
323 // return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
324 return 0;
325}
326
327////////////////////////////////////////////////////////////////////////////////
328/// Resize a gVirtualX Pixmap.
329
331{
332 return gVirtualX->ResizePixmap(device, w, h);
333}
334
335////////////////////////////////////////////////////////////////////////////////
336/// Call gVirtualX->ClearWindow()
337
339{
340 gVirtualX->ClearWindow();
341}
342
343////////////////////////////////////////////////////////////////////////////////
344/// Returns true when cocoa backend is used
345
347{
348 return gVirtualX->InheritsFrom("TGCocoa");
349}
350
351////////////////////////////////////////////////////////////////////////////////
352///Not required at the moment.
353
354void TGLPadPainter::CopyDrawable(Int_t /* device */, Int_t /* px */, Int_t /* py */)
355{
356 // gVirtualX->CopyPixmap(device, px, py);
357}
358
359////////////////////////////////////////////////////////////////////////////////
360///Not required at the moment.
361
363{
364 // gVirtualX->SelectWindow(device);
365 // gVirtualX->ClosePixmap();
366}
367
368////////////////////////////////////////////////////////////////////////////////
369///For gVirtualX this means select pixmap (or window)
370///and all subsequent drawings will go into
371///this pixmap. For OpenGL this means the change of
372///coordinate system and viewport.
373
375{
376 if (fLocked)
377 return;
378
379 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
380 Int_t px = 0, py = 0;
381
382 pad->XYtoAbsPixel(pad->GetX1(), pad->GetY1(), px, py);
383
384 py = gPad->GetWh() - py;
385 //
388
389 glViewport(GLint(px * scale), GLint(py * scale),
390 GLsizei(gPad->GetWw() * pad->GetAbsWNDC() * scale),
391 GLsizei(gPad->GetWh() * pad->GetAbsHNDC() * scale));
392
395 glOrtho(pad->GetX1(), pad->GetX2(), pad->GetY1(), pad->GetY2(), -10., 10.);
396
399 glTranslated(0., 0., -1.);
400 } else {
401 ::Error("TGLPadPainter::SelectDrawable",
402 "function was called not from TPad or TCanvas code\n");
403 throw std::runtime_error("");
404 }
405}
406
407////////////////////////////////////////////////////////////////////////////////
408///Init gl-pad painter:
409///1. 2D painter does not use depth test, should not modify
410/// depth-buffer content (except initial cleanup).
411///2. Disable cull face.
412///3. Disable lighting.
413///4. Set viewport (to the whole canvas area).
414///5. Set camera.
415///6. Unlock painter.
416
418{
419 static bool gl_init = false;
420 if (!gl_init) {
422 if (version == 0)
423 Warning("TGLPadPainter::InitPainter", "GL initalization failed.");
424 else if (gDebug > 0)
425 Info("TGLPadPainter::InitPainter", "GL initalization successful.");
426 gl_init = true;
427 }
431
432 //Clear the buffer
433 glViewport(0, 0, GLsizei(gPad->GetWw()), GLsizei(gPad->GetWh()));
434
436 glClearColor(1.,1.,1.,1.);
439
442
443 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
444
447 glTranslated(0., 0., -1.);
448
449 fLocked = kFALSE;
450}
451
452////////////////////////////////////////////////////////////////////////////////
453///When TPad::Range for gPad is called, projection
454///must be changed in OpenGL.
455
457{
458 if (fLocked) return;
459
462
463 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
464
466}
467
468////////////////////////////////////////////////////////////////////////////////
469///Locked state of painter means, that
470///GL context can be invalid, so no GL calls
471///can be executed.
472
474{
475 if (fLocked) return;
476
477 glFinish();
478 fLocked = kTRUE;
479}
480
481/*
4822D primitives.
483*/
484
486
487////////////////////////////////////////////////////////////////////////////////
488///Draw line segment.
489
491{
492 if (fLocked) {
493 //GL pad painter can be called in non-standard situation:
494 //not from TPad::Paint, but
495 //from TView3D::ExecuteRotateView. This means in fact,
496 //that TView3D wants to draw itself in a XOR mode, via
497 //gVirtualX.
498 if (gVirtualX->GetDrawMode() == TVirtualX::kInvert) {
499 gVirtualX->DrawLine(gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
500 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2));
501 }
502
503 return;
504 }
505
507
508 glBegin(GL_LINES);
509 glVertex2d(x1, y1);
510 glVertex2d(x2, y2);
511 glEnd();
512
513 if (gVirtualX->GetLineWidth() > lineWidthTS) {
514 Double_t pointSize = gVirtualX->GetLineWidth();
520 glBegin(GL_POINTS);
521
522 glVertex2d(x1, y1);
523 glVertex2d(x2, y2);
524
525 glEnd();
526 glPointSize(1.f);
527 }
528
529}
530
531////////////////////////////////////////////////////////////////////////////////
532///Draw line segment in NDC coordinates.
533
535{
536 if (fLocked) return;
537
539 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
540 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
541
542 glBegin(GL_LINES);
543 glVertex2d(gPad->GetX1() + u1 * xRange, gPad->GetY1() + v1 * yRange);
544 glVertex2d(gPad->GetX1() + u2 * xRange, gPad->GetY1() + v2 * yRange);
545 glEnd();
546}
547
548////////////////////////////////////////////////////////////////////////////////
549///Draw filled or hollow box.
550
552{
553 if (fLocked) return;
554
555 if (IsGradientFill(gVirtualX->GetFillColor())) {
556 Double_t xs[] = {x1, x2, x2, x1};
557 Double_t ys[] = {y1, y1, y2, y2};
559 return;
560 }
561
562 if (mode == kHollow) {
564 //
566 glRectd(x1, y1, x2, y2);
568 glLineWidth(1.f);
569 } else {
570 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE);//Set filling parameters.
571 glRectd(x1, y1, x2, y2);
572 }
573}
574
575////////////////////////////////////////////////////////////////////////////////
576///Draw tesselated polygon (probably, outline only).
577
579{
580 assert(x != nullptr && "DrawFillArea, parameter 'x' is null");
581 assert(y != nullptr && "DrawFillArea, parameter 'y' is null");
582
583 if (fLocked)
584 return;
585
586 if (n < 3) {
587 ::Error("TGLPadPainter::DrawFillArea",
588 "invalid number of points in a polygon");
589 return;
590 }
591
592 if (IsGradientFill(gVirtualX->GetFillColor()))
593 return DrawPolygonWithGradient(n, x, y);
594
595 if (!gVirtualX->GetFillStyle()) {
597 return DrawPolyLine(n, x, y);
598 }
599
601 DrawTesselation(n, x, y);
602}
603
604////////////////////////////////////////////////////////////////////////////////
605///Draw tesselated polygon (never called, probably, since TPad::PaintFillArea for floats
606///is deprecated).
607
609{
610 if (fLocked) return;
611
612 if (!gVirtualX->GetFillStyle()) {
614 return DrawPolyLine(n, x, y);
615 }
616
617 fVs.resize(n * 3);
618
619 for (Int_t i = 0; i < n; ++i) {
620 fVs[i * 3] = x[i];
621 fVs[i * 3 + 1] = y[i];
622 }
623
625
629
630 for (Int_t i = 0; i < n; ++i)
631 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
632
633
634 gluEndPolygon(t);
635}
636
637////////////////////////////////////////////////////////////////////////////////
638///Draw poly-line in user coordinates.
639
641{
642 if (fLocked) return;
643
645
646 glBegin(GL_LINE_STRIP);
647
648 for (Int_t i = 0; i < n; ++i)
649 glVertex2d(x[i], y[i]);
650
651 if (fIsHollowArea) {
652 glVertex2d(x[0], y[0]);
654 }
655 glEnd();
656
657 if (gVirtualX->GetLineWidth() > lineWidthTS) {
658 Double_t pointSize = gVirtualX->GetLineWidth();
664 glBegin(GL_POINTS);
665
666 for (Int_t i = 0; i < n; ++i)
667 glVertex2d(x[i], y[i]);
668
669 glEnd();
670 glPointSize(1.f);
671 }
672}
673
674////////////////////////////////////////////////////////////////////////////////
675///Never called?
676
678{
679 if (fLocked) return;
680
682
683 glBegin(GL_LINE_STRIP);
684
685 for (Int_t i = 0; i < n; ++i)
686 glVertex2f(x[i], y[i]);
687
688 if (fIsHollowArea) {
689 glVertex2f(x[0], y[0]);
691 }
692
693 glEnd();
694}
695
696////////////////////////////////////////////////////////////////////////////////
697///Poly line in NDC.
698
700{
701 if (fLocked) return;
702
704 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
705 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
706 const Double_t x1 = gPad->GetX1(), y1 = gPad->GetY1();
707
708 glBegin(GL_LINE_STRIP);
709
710 for (Int_t i = 0; i < n; ++i)
711 glVertex2d(x1 + u[i] * xRange, y1 + v[i] * yRange);
712
713 glEnd();
714}
715
716namespace {
717
718//Aux. function.
719template<class ValueType>
720void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst);
721
722}
723
724////////////////////////////////////////////////////////////////////////////////
725///Poly-marker.
726
728{
729 if (fLocked) return;
730
733}
734
735////////////////////////////////////////////////////////////////////////////////
736///Poly-marker.
737
739{
740 if (fLocked) return;
741
744}
745
746////////////////////////////////////////////////////////////////////////////////
747///Poly-marker.
748
750{
751 if (fLocked) return;
752
755 //
756 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
757 //
759 //
761
762 Float_t rgba[4] = {};
763 Rgl::Pad::ExtractRGBA(gVirtualX->GetMarkerColor(), rgba);
766
767 const Width_t w = TMath::Max(1, Int_t(TAttMarker::GetMarkerLineWidth(gVirtualX->GetMarkerStyle())));
769
770 const TPoint *xy = &fPoly[0];
772 const UInt_t n = UInt_t(fPoly.size());
773 switch (markerStyle) {
774 case kDot:
776 break;
777 case kPlus:
779 break;
780 case kStar:
781 case 31:
783 break;
784 case kCircle:
785 case kOpenCircle:
787 break;
788 case kMultiply:
789 fMarker.DrawX(n, xy);
790 break;
791 case kFullDotSmall://"Full dot small"
793 break;
794 case kFullDotMedium:
796 break;
797 case kFullDotLarge:
798 case kFullCircle:
800 break;
801 case kFullSquare:
803 break;
804 case kFullTriangleUp:
806 break;
809 break;
810 case kOpenSquare:
814 break;
815 case kOpenTriangleUp:
819 break;
820 case kOpenDiamond:
822 break;
823 case kOpenCross:
825 break;
826 case kFullStar:
828 break;
829 case kOpenStar:
831 break;
834 break;
835 case kFullDiamond:
837 break;
838 case kFullCross:
840 break;
843 break;
846 break;
849 break;
850 case kOctagonCross:
852 break;
855 break;
858 break;
861 break;
864 break;
867 break;
870 break;
873 break;
874 case kOpenCrossX:
876 break;
877 case kFullCrossX:
879 break;
880 case kFourSquaresX:
882 break;
883 case kFourSquaresPlus:
885 break;
886 }
887
890 glLineWidth(1.f);
891}
892
893////////////////////////////////////////////////////////////////////////////////
894
895template<class Char>
897{
899
901 //
902 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
903 //
905
906 Float_t rgba[4] = {};
907 Rgl::Pad::ExtractRGBA(gVirtualX->GetTextColor(), rgba);
909
910 //10 is the first valid font index.
911 //20 is FreeSerifBold, as in TTF.cxx and in TGLFontManager.cxx.
912 //shift - is the shift to access "extended" fonts.
914
915 Int_t fontIndex = TMath::Max(Short_t(10), gVirtualX->GetTextFont());
916 if (fontIndex / 10 + shift > TGLFontManager::GetFontFileArray()->GetEntries())
917 fontIndex = 20 + shift * 10;
918 else
919 fontIndex += shift * 10;
920
921 fFM.RegisterFont(TMath::Max(Int_t(gVirtualX->GetTextSize()) - 1, 10),//kTexture does not work if size < 10.
924 fF.PreRender();
925
926 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
927 fF.Render(text, gPad->XtoPixel(x), padH - gPad->YtoPixel(y), GetTextAngle(), GetTextMagnitude());
928
929 fF.PostRender();
931
933}
934
935////////////////////////////////////////////////////////////////////////////////
936///Draw text. This operation is especially
937///dangerous if in locked state -
938///ftgl will assert on zero texture size
939///(which is result of bad GL context).
940
942{
943 if (fLocked) return;
944
945 if (!gVirtualX->GetTextSize())
946 return;
947
949}
950
951////////////////////////////////////////////////////////////////////////////////
952///Draw text. This operation is especially
953///dangerous if in locked state -
954///ftgl will assert on zero texture size
955///(which is result of bad GL context).
956
958{
959 if (fLocked) return;
960
961 if (!gVirtualX->GetTextSize())
962 return;
963
965}
966
967////////////////////////////////////////////////////////////////////////////////
968///Draw text in NDC. This operation is especially
969///dangerous if in locked state -
970///ftgl will assert on zero texture size
971///(which is result of bad GL context).
972
974{
975 if (fLocked) return;
976
977 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
978 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
979 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
980}
981
982////////////////////////////////////////////////////////////////////////////////
983///Draw text in NDC. This operation is especially
984///dangerous if in locked state -
985///ftgl will assert on zero texture size
986///(which is result of bad GL context).
987
989{
990 if (fLocked) return;
991
992 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
993 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
994 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
995}
996
997////////////////////////////////////////////////////////////////////////////////
998///Save the projection matrix.
999///Attention! GL_PROJECTION will become the current matrix
1000///after this call!
1001
1007
1008////////////////////////////////////////////////////////////////////////////////
1009///Restore the projection matrix.
1010///Attention! GL_PROJECTION will become the current matrix
1011///after this call!
1012
1018
1019////////////////////////////////////////////////////////////////////////////////
1020///Save the modelview matrix.
1021///Attention! GL_MODELVIEW will become the current matrix
1022///after this call!
1023
1029
1030////////////////////////////////////////////////////////////////////////////////
1031///Restore the modelview matrix.
1032///Attention! GL_MODELVIEW will become the current matrix
1033///after this call!
1034
1040
1041////////////////////////////////////////////////////////////////////////////////
1042///Extract and save the current viewport.
1043
1048
1049////////////////////////////////////////////////////////////////////////////////
1050///Restore the saved viewport.
1051
1053{
1054 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
1055}
1056
1057////////////////////////////////////////////////////////////////////////////////
1058/// Using TImage save frame-buffer contents as a picture.
1059
1060void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
1061{
1062 TVirtualPad *canvas = (TVirtualPad *)pad->GetCanvas();
1063 if (!canvas)
1064 return;
1065
1066 gROOT->ProcessLine(Form("((TCanvas *)0x%zx)->Flush();", (size_t)canvas));
1067
1068 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
1071 //In case GL_BGRA is not in gl.h (old windows' gl) - comment/uncomment lines.
1072 //glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_BGRA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
1073 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
1074
1075 std::unique_ptr<TImage> image(TImage::Create());
1076 if (!image.get()) {
1077 ::Error("TGLPadPainter::SaveImage", "TImage creation failed");
1078 return;
1079 }
1080
1081 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
1082 UInt_t *argb = image->GetArgbArray();
1083
1084 if (!argb) {
1085 ::Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
1086 return;
1087 }
1088
1089 const Int_t nLines = canvas->GetWh();
1090 const Int_t nPixels = canvas->GetWw();
1091
1092 for (Int_t i = 0; i < nLines; ++i) {
1093 Int_t base = (nLines - 1 - i) * nPixels;
1094 for (Int_t j = 0; j < nPixels; ++j, ++base) {
1095 //Uncomment/comment if you don't have GL_BGRA.
1096
1097 const UInt_t pix = buff[base];
1098 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
1099 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
1100
1101 //argb[i * nPixels + j] = buff[base];
1102 argb[i * nPixels + j] = bgra;
1103 }
1104 }
1105
1106 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
1107}
1108
1109////////////////////////////////////////////////////////////////////////////////
1110
1113{
1114 if (fLocked)
1115 return;
1116
1117 if (!pixelData) {
1118 //I'd prefer an assert.
1119 ::Error("TGLPadPainter::DrawPixels", "pixel data is null");
1120 return;
1121 }
1122
1123 if (std::numeric_limits<UInt_t>::digits >= 32) {
1124 //TASImage uses bit 31 as ...
1125 //alpha channel flag! FUUUUUUUUUUUUU ..... !!!
1126 CLRBIT(width, 31);
1127 CLRBIT(height, 31);
1128 }
1129
1130 if (!width) {
1131 //Assert is better.
1132 ::Error("TGLPadPainter::DrawPixels", "invalid width");
1133 return;
1134 }
1135
1136 if (!height) {
1137 //Assert is better.
1138 ::Error("TGLPadPainter::DrawPixels", "invalid height");
1139 return;
1140 }
1141
1142 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
1143 //TASImage passes pixel coordinates in pad's pixmap coordinate space.
1144 //While glRasterPosX said to work with 'window' coordinates,
1145 //that's a lie :) it does not :)
1146
1147 const Double_t rasterX = Double_t(dstX) / (pad->GetAbsWNDC() * pad->GetWw()) *
1148 (pad->GetX2() - pad->GetX1()) + pad->GetX1();
1149
1150 const Double_t yRange = pad->GetY2() - pad->GetY1();
1151 const Double_t rasterY = yRange - Double_t(dstY + height) / (pad->GetAbsHNDC() * pad->GetWh()) * yRange +
1152 pad->GetY1();
1153
1154 GLdouble oldPos[4] = {};
1155 //Save the previous raster pos.
1157
1159 //Stupid asimage provides us upside-down image.
1160 std::vector<unsigned char> upsideDownImage(4 * width * height);
1161 const unsigned char *srcLine = pixelData + 4 * width * (height - 1);
1162 unsigned char *dstLine = &upsideDownImage[0];
1163 for (UInt_t i = 0; i < height; ++i, srcLine -= 4 * width, dstLine += 4 * width)
1164 std::copy(srcLine, srcLine + 4 * width, dstLine);
1165
1166 if (enableBlending) {
1169 }
1170
1172
1173 if (enableBlending)
1175
1176 //Restore raster pos.
1177 glRasterPos2d(oldPos[0], oldPos[1]);
1178 } else
1179 ::Error("TGLPadPainter::DrawPixels", "no pad found to draw");
1180}
1181
1182//Aux. functions - gradient and solid fill of arbitrary area.
1183
1184////////////////////////////////////////////////////////////////////////////////
1185///At the moment I assume both linear and radial gradients will work the same way -
1186///using a stencil buffer and some big rectangle(s) to fill with a gradient.
1187///Thus I have a 'common' part - the part responsible for a stencil test.
1188
1190{
1191 assert(n > 2 && "DrawPolygonWithGradient, invalid number of points");
1192 assert(x != nullptr && "DrawPolygonWithGradient, parameter 'x' is null");
1193 assert(y != nullptr && "DrawPolygonWithGradient, parameter 'y' is null");
1194
1195 assert(dynamic_cast<TColorGradient *>(gROOT->GetColor(gVirtualX->GetFillColor())) != nullptr &&
1196 "DrawPolygonWithGradient, the current fill color is not a gradient fill");
1197 const TColorGradient * const grad =
1198 dynamic_cast<TColorGradient *>(gROOT->GetColor(gVirtualX->GetFillColor()));
1199
1200 if (fLocked)
1201 return;
1202
1203 //Now, some magic!
1205
1206 //TODO: check that the state is restored back correctly after
1207 // we done with a gradient.
1208 //TODO: make sure that we have glDepthMask set to false in general!
1210
1211 glStencilFunc(GL_NEVER, 1, 0xFF);
1212 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);// draw 1s on test fail (always)
1213 //Draw stencil pattern
1214 glStencilMask(0xFF);
1216
1217 //Draw our polygon into the stencil buffer:
1218 DrawTesselation(n, x, y);
1219
1221 glStencilMask(0x00);
1222 //Draw where stencil's value is 0
1223 glStencilFunc(GL_EQUAL, 0, 0xFF);
1224 //Draw only where stencil's value is 1
1225 glStencilFunc(GL_EQUAL, 1, 0xFF);
1226
1227 //At the moment radial gradient is derived from linear - it was convenient
1228 //at some point, but in fact it was a bad idea. And now I have to
1229 //first check radial gradient.
1230 //TODO: TRadialGradient must inherit TColorGradient directly.
1231 const TRadialGradient * const rGrad = dynamic_cast<const TRadialGradient *>(grad);
1232 if (rGrad)
1233 DrawGradient(rGrad, n, x, y);
1234 else {
1235 const TLinearGradient * const lGrad = dynamic_cast<const TLinearGradient *>(grad);
1236 assert(lGrad != nullptr && "DrawPolygonWithGradient, unknown gradient type");
1237 DrawGradient(lGrad, n, x, y);
1238 }
1239}
1240
1241////////////////////////////////////////////////////////////////////////////////
1242
1244 const Double_t *xs, const Double_t *ys)
1245{
1246 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1247 assert(nPoints > 2 && "DrawGradient, invalid number of points");
1248 assert(xs != nullptr && "DrawGradient, parameter 'xs' is null");
1249 assert(ys != nullptr && "DrawGradient, parameter 'ys' is null");
1250
1252 ::Warning("TGLPadPainter::DrawGradient",
1253 "extended radial gradient is not supported");//yet?
1254 return;
1255 }
1256
1257 //TODO: check the polygon's bbox!
1258 const auto &bbox = Rgl::Pad::FindBoundingRect(nPoints, xs, ys);
1259 //
1260 auto center = grad->GetCenter();
1261 auto radius = grad->GetRadius();
1262 //Adjust the center and radius depending on coordinate mode.
1264 radius *= TMath::Max(bbox.fWidth, bbox.fHeight);
1265 center.fX = bbox.fWidth * center.fX + bbox.fXMin;
1266 center.fY = bbox.fHeight * center.fY + bbox.fYMin;
1267 } else {
1268 const auto w = gPad->GetX2() - gPad->GetX1();
1269 const auto h = gPad->GetY2() - gPad->GetY1();
1270
1271 radius *= TMath::Max(w, h);
1272 center.fX *= w;
1273 center.fY *= h;
1274 }
1275 //Now for the gradient fill we switch into pixel coordinates:
1276 const auto pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1277 const auto pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1278 //
1281 //A new ortho projection:
1284 //
1285 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1286 //
1288 center.fX = gPad->XtoPixel(center.fX);
1289 center.fY = pixelH - gPad->YtoPixel(center.fY);
1290
1291 Double_t maxR = 0.;
1292 {
1293 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1294 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1295 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1296 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1297 //Get the longest distance from the center to the bounding box vertices
1298 //(this will be the maximum possible radius):
1299 const Double_t maxDistX = TMath::Max(TMath::Abs(center.fX - xMin),
1300 TMath::Abs(center.fX - xMax));
1301 const Double_t maxDistY = TMath::Max(TMath::Abs(center.fY - yMin),
1302 TMath::Abs(center.fY - yMax));
1304 }
1305
1306 //If gradient 'stops inside the polygon', we use
1307 //the solid fill for the area outside of radial gradient:
1308 const Bool_t solidFillAfter = maxR > radius;
1309 //We emulate a radial gradient using triangles and linear gradient:
1310 //TODO: Can be something smarter? (btw even 100 seems to be enough)
1311 const UInt_t nSlices = 500;
1312
1313 const auto nColors = grad->GetNumberOfSteps();
1314 //+1 - the strip from the last color's position to radius,
1315 //and (probably) + 1 for solidFillAfter.
1316 const auto nCircles = nColors + 1 + solidFillAfter;
1317
1318 //TODO: can locations be outside of [0., 1.] ???
1319 //at the moment I assume the answer is NO, NEVER.
1320 const auto locations = grad->GetColorPositions();
1321 // * 2 below == x,y
1322 std::vector<Double_t> circles(nSlices * nCircles * 2);
1323 const Double_t angle = TMath::TwoPi() / nSlices;
1324
1325 //"Main" circles (for colors at locations[i]).
1326 for (UInt_t i = 0; i < nColors; ++i) {
1327 const auto circle = &circles[i * nSlices * 2];
1328 //TODO: either check locations here or somewhere else.
1329 const auto r = radius * locations[i];
1330 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1331 circle[j] = center.fX + r * TMath::Cos(angle * j);
1332 circle[j + 1] = center.fY + r * TMath::Sin(angle * j);
1333 }
1334 //The "closing" vertices:
1335 circle[(nSlices - 1) * 2] = circle[0];
1336 circle[(nSlices - 1) * 2 + 1] = circle[1];
1337 }
1338
1339 {
1340 //The strip between lastPos and radius:
1341 const auto circle = &circles[nColors * nSlices * 2];
1342 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1343 circle[j] = center.fX + radius * TMath::Cos(angle * j);
1344 circle[j + 1] = center.fY + radius * TMath::Sin(angle * j);
1345 }
1346
1347 circle[(nSlices - 1) * 2] = circle[0];
1348 circle[(nSlices - 1) * 2 + 1] = circle[1];
1349 }
1350
1351 if (solidFillAfter) {
1352 //The strip after the radius:
1353 const auto circle = &circles[(nCircles - 1) * nSlices * 2];
1354 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1355 circle[j] = center.fX + maxR * TMath::Cos(angle * j);
1356 circle[j + 1] = center.fY + maxR * TMath::Sin(angle * j);
1357 }
1358
1359 circle[(nSlices - 1) * 2] = circle[0];
1360 circle[(nSlices - 1) * 2 + 1] = circle[1];
1361 }
1362
1363 //Now we draw:
1364 //1) triangle fan in the center (from center to the locations[1],
1365 // with a solid fill).
1366 //2) quad strips for colors.
1367 //3) additional quad strip from the lastLocation to the radius
1368 //4) additional quad strip (if any) from the radius to maxR.
1369
1370 //RGBA values:
1371 const auto rgba = grad->GetColors();
1372
1374 //TODO?
1376
1377 //Probably a degenerated case. Maybe not.
1380 glVertex2d(center.fX, center.fY);
1381
1382 for (UInt_t i = 0, e = nSlices * 2; i < e; i += 2)
1383 glVertex2dv(&circles[i]);
1384
1385 glEnd();
1386
1387 //No auto for circles, explicit types to have const Double_t * const, not Duble_t * const.
1388 for (UInt_t i = 0; i < nColors - 1; ++i) {
1389 const Double_t * const inner = &circles[i * nSlices * 2];
1390 const auto innerRGBA = rgba + i * 4;
1391 const auto outerRGBA = rgba + (i + 1) * 4;
1392 const Double_t * const outer = &circles[(i + 1) * nSlices * 2];
1393
1395 }
1396
1397 //Probably degenerated strip.
1398 {
1399 const Double_t * const inner = &circles[nSlices * (nColors - 1) * 2];
1400 const auto solidRGBA = rgba + (nColors - 1) * 4;
1401 const Double_t * const outer = &circles[nSlices * nColors * 2];
1402
1404 }
1405
1406 if (solidFillAfter) {
1407 const Double_t * const inner = &circles[nSlices * nColors * 2];
1408 const auto solidRGBA = rgba + (nColors - 1) * 4;
1409 const Double_t * const outer = &circles[nSlices * (nColors + 1) * 2];
1410
1412 }
1413
1416}
1417
1418////////////////////////////////////////////////////////////////////////////////
1419
1421 const Double_t *x, const Double_t *y)
1422{
1423 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1424 assert(n > 2 && "DrawGradient, invalid number of points");
1425 assert(x != nullptr && "DrawGradient, parameter 'x' is null");
1426 assert(y != nullptr && "DrawGradient, parameter 'y' is null");
1427
1428 //Now we fill the whole scene with one big rectangle
1429 //(group of rectangles) with a gradient fill using
1430 //stencil test.
1431
1432 //Find a bounding rect.
1433 const auto &bbox = Rgl::Pad::FindBoundingRect(n, x, y);
1434 //TODO: check the bbox??
1435
1436 //For the gradient fill we switch into the
1437 //pixel coordinates.
1440
1441 //A new ortho projection:
1444
1445 const Double_t pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1446 const Double_t pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1447 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1448
1449 //A new modelview:
1452 //
1453 TColorGradient::Point start = grad->GetStart();
1454 TColorGradient::Point end = grad->GetEnd();
1455
1456 //Change gradient coordinates from 'NDC' to pad coords:
1458 {
1459 const Double_t w = gPad->GetX2() - gPad->GetX1();
1460 const Double_t h = gPad->GetY2() - gPad->GetY1();
1461
1462 start.fX = start.fX * w;
1463 start.fY = start.fY * h;
1464 end.fX = end.fX * w;
1465 end.fY = end.fY * h;
1466 } else {
1467 start.fX = start.fX * bbox.fWidth + bbox.fXMin;
1468 start.fY = start.fY * bbox.fHeight + bbox.fYMin;
1469 end.fX = end.fX * bbox.fWidth + bbox.fXMin;
1470 end.fY = end.fY * bbox.fHeight + bbox.fYMin;
1471 }
1472
1473 //TODO: with a radial fill we'll have to extract the code
1474 // below into the separate function/and have additional function
1475 // for a radial gradient.
1476 //Now from pad to pixels:
1477 start.fX = gPad->XtoPixel(start.fX);
1478 start.fY = pixelH - gPad->YtoPixel(start.fY);
1479 end.fX = gPad->XtoPixel(end.fX);
1480 end.fY = pixelH - gPad->YtoPixel(end.fY);
1481 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1482 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1483 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1484 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1485 //
1486
1487 //TODO: check all calculations!
1488
1489 //Get the longest distance from the start point to the bounding box vertices:
1490 const Double_t maxDistX = TMath::Max(TMath::Abs(start.fX - xMin), TMath::Abs(start.fX - xMax));
1491 const Double_t maxDistY = TMath::Max(TMath::Abs(start.fY - yMin), TMath::Abs(start.fY - yMax));
1492
1493 const Double_t startEndLength = TMath::Sqrt((end.fX - start.fX) * (end.fX - start.fX) +
1494 (end.fY - start.fY) * (end.fY - start.fY));
1497
1498 //Boxes with a gradients to emulate gradient fill with many colors:
1499 const Double_t * const colorPositions = grad->GetColorPositions();
1500 std::vector<Double_t> gradBoxes(grad->GetNumberOfSteps() + 2);
1501 gradBoxes[0] = start.fY - h;
1502 for (unsigned i = 1; i <= grad->GetNumberOfSteps(); ++i)
1503 gradBoxes[i] = startEndLength * colorPositions[i - 1] + start.fY;
1504
1505 gradBoxes[grad->GetNumberOfSteps() + 1] = start.fY + h;
1506
1507 //Rotation angle - gradient's axis:
1508 Double_t angle = TMath::ACos((startEndLength * (end.fY - start.fY)) /
1510 if (end.fX > start.fX)
1511 angle *= -1;
1512
1513 glTranslated(start.fX, start.fY, 0.);
1514 glRotated(angle, 0., 0., 1.);
1515 glTranslated(-start.fX, -start.fY, 0.);
1516 //
1517 const Double_t * const rgba = grad->GetColors();
1518
1519 const unsigned nEdges = gradBoxes.size();
1520 const unsigned nColors = grad->GetNumberOfSteps();
1521 const Double_t xLeft = start.fX - h, xRight = start.fX + h;
1522
1524 //TODO?
1526
1529 rgba + (nColors - 1) * 4, rgba + (nColors - 1) * 4);
1530
1531 for (unsigned i = 1; i < nEdges - 2; ++i)
1533 xRight, rgba + (i - 1) * 4, rgba + i * 4);
1534
1537}
1538
1539////////////////////////////////////////////////////////////////////////////////
1540
1542{
1543 assert(n > 2 && "DrawTesselation, invalid number of points");
1544 assert(x != nullptr && "DrawTesselation, parameter 'x' is null");
1545 assert(y != nullptr && "DrawTesselation, parameter 'y' is null");
1546
1547 //Data for a tesselator:
1548 fVs.resize(n * 3);
1549
1550 for (Int_t i = 0; i < n; ++i) {
1551 fVs[i * 3] = x[i];
1552 fVs[i * 3 + 1] = y[i];
1553 fVs[i * 3 + 2] = 0.;
1554 }
1555
1556 //TODO: A very primitive way to tesselate - check what
1557 //kind of polygons we can really have from TPad/TCanvas.
1559 gluBeginPolygon(t);
1561
1562 for (Int_t i = 0; i < n; ++i)
1563 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
1564
1565 gluEndPolygon(t);
1566}
1567
1568
1569//Aux. functions.
1570namespace {
1571
1572template<class ValueType>
1573void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst)
1574{
1575 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
1576
1577 dst.resize(n);
1578 for (Int_t i = 0; i < n; ++i) {
1579 dst[i].fX = gPad->XtoPixel(x[i]);
1580 dst[i].fY = padH - gPad->YtoPixel(y[i]);
1581 }
1582}
1583
1584}
1585
#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
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2495
#define gPad
#define gVirtualX
Definition TVirtualX.h:338
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 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.
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.
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
virtual UInt_t GetWh() const =0
virtual UInt_t GetWw() const =0
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