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"Pixmap" part of TGLPadPainter.
262*/
263
264////////////////////////////////////////////////////////////////////////////////
265///Not required at the moment.
266
268{
269 return 0;
270}
271
272////////////////////////////////////////////////////////////////////////////////
273///Not required at the moment.
274
278
279////////////////////////////////////////////////////////////////////////////////
280///Not required at the moment.
281
282void TGLPadPainter::CopyDrawable(Int_t /*device*/, Int_t /*px*/, Int_t /*py*/)
283{
284}
285
286////////////////////////////////////////////////////////////////////////////////
287///Not required at the moment.
288
290{
291}
292
293////////////////////////////////////////////////////////////////////////////////
294///For gVirtualX this means select pixmap (or window)
295///and all subsequent drawings will go into
296///this pixmap. For OpenGL this means the change of
297///coordinate system and viewport.
298
300{
301 if (fLocked)
302 return;
303
304 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
305 Int_t px = 0, py = 0;
306
307 pad->XYtoAbsPixel(pad->GetX1(), pad->GetY1(), px, py);
308
309 py = gPad->GetWh() - py;
310 //
313
314 glViewport(GLint(px * scale), GLint(py * scale),
315 GLsizei(gPad->GetWw() * pad->GetAbsWNDC() * scale),
316 GLsizei(gPad->GetWh() * pad->GetAbsHNDC() * scale));
317
320 glOrtho(pad->GetX1(), pad->GetX2(), pad->GetY1(), pad->GetY2(), -10., 10.);
321
324 glTranslated(0., 0., -1.);
325 } else {
326 ::Error("TGLPadPainter::SelectDrawable",
327 "function was called not from TPad or TCanvas code\n");
328 throw std::runtime_error("");
329 }
330}
331
332////////////////////////////////////////////////////////////////////////////////
333///Init gl-pad painter:
334///1. 2D painter does not use depth test, should not modify
335/// depth-buffer content (except initial cleanup).
336///2. Disable cull face.
337///3. Disable lighting.
338///4. Set viewport (to the whole canvas area).
339///5. Set camera.
340///6. Unlock painter.
341
343{
344 static bool gl_init = false;
345 if (!gl_init) {
347 if (version == 0)
348 Warning("TGLPadPainter::InitPainter", "GL initalization failed.");
349 else if (gDebug > 0)
350 Info("TGLPadPainter::InitPainter", "GL initalization successful.");
351 gl_init = true;
352 }
356
357 //Clear the buffer
358 glViewport(0, 0, GLsizei(gPad->GetWw()), GLsizei(gPad->GetWh()));
359
361 glClearColor(1.,1.,1.,1.);
364
367
368 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
369
372 glTranslated(0., 0., -1.);
373
374 fLocked = kFALSE;
375}
376
377////////////////////////////////////////////////////////////////////////////////
378///When TPad::Range for gPad is called, projection
379///must be changed in OpenGL.
380
382{
383 if (fLocked) return;
384
387
388 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
389
391}
392
393////////////////////////////////////////////////////////////////////////////////
394///Locked state of painter means, that
395///GL context can be invalid, so no GL calls
396///can be executed.
397
399{
400 if (fLocked) return;
401
402 glFinish();
403 fLocked = kTRUE;
404}
405
406/*
4072D primitives.
408*/
409
411
412////////////////////////////////////////////////////////////////////////////////
413///Draw line segment.
414
416{
417 if (fLocked) {
418 //GL pad painter can be called in non-standard situation:
419 //not from TPad::Paint, but
420 //from TView3D::ExecuteRotateView. This means in fact,
421 //that TView3D wants to draw itself in a XOR mode, via
422 //gVirtualX.
423 if (gVirtualX->GetDrawMode() == TVirtualX::kInvert) {
424 gVirtualX->DrawLine(gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
425 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2));
426 }
427
428 return;
429 }
430
432
433 glBegin(GL_LINES);
434 glVertex2d(x1, y1);
435 glVertex2d(x2, y2);
436 glEnd();
437
438 if (gVirtualX->GetLineWidth() > lineWidthTS) {
439 Double_t pointSize = gVirtualX->GetLineWidth();
445 glBegin(GL_POINTS);
446
447 glVertex2d(x1, y1);
448 glVertex2d(x2, y2);
449
450 glEnd();
451 glPointSize(1.f);
452 }
453
454}
455
456////////////////////////////////////////////////////////////////////////////////
457///Draw line segment in NDC coordinates.
458
460{
461 if (fLocked) return;
462
464 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
465 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
466
467 glBegin(GL_LINES);
468 glVertex2d(gPad->GetX1() + u1 * xRange, gPad->GetY1() + v1 * yRange);
469 glVertex2d(gPad->GetX1() + u2 * xRange, gPad->GetY1() + v2 * yRange);
470 glEnd();
471}
472
473////////////////////////////////////////////////////////////////////////////////
474///Draw filled or hollow box.
475
477{
478 if (fLocked) return;
479
480 if (IsGradientFill(gVirtualX->GetFillColor())) {
481 Double_t xs[] = {x1, x2, x2, x1};
482 Double_t ys[] = {y1, y1, y2, y2};
484 return;
485 }
486
487 if (mode == kHollow) {
489 //
491 glRectd(x1, y1, x2, y2);
493 glLineWidth(1.f);
494 } else {
495 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE);//Set filling parameters.
496 glRectd(x1, y1, x2, y2);
497 }
498}
499
500////////////////////////////////////////////////////////////////////////////////
501///Draw tesselated polygon (probably, outline only).
502
504{
505 assert(x != nullptr && "DrawFillArea, parameter 'x' is null");
506 assert(y != nullptr && "DrawFillArea, parameter 'y' is null");
507
508 if (fLocked)
509 return;
510
511 if (n < 3) {
512 ::Error("TGLPadPainter::DrawFillArea",
513 "invalid number of points in a polygon");
514 return;
515 }
516
517 if (IsGradientFill(gVirtualX->GetFillColor()))
518 return DrawPolygonWithGradient(n, x, y);
519
520 if (!gVirtualX->GetFillStyle()) {
522 return DrawPolyLine(n, x, y);
523 }
524
526 DrawTesselation(n, x, y);
527}
528
529////////////////////////////////////////////////////////////////////////////////
530///Draw tesselated polygon (never called, probably, since TPad::PaintFillArea for floats
531///is deprecated).
532
534{
535 if (fLocked) return;
536
537 if (!gVirtualX->GetFillStyle()) {
539 return DrawPolyLine(n, x, y);
540 }
541
542 fVs.resize(n * 3);
543
544 for (Int_t i = 0; i < n; ++i) {
545 fVs[i * 3] = x[i];
546 fVs[i * 3 + 1] = y[i];
547 }
548
550
554
555 for (Int_t i = 0; i < n; ++i)
556 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
557
558
559 gluEndPolygon(t);
560}
561
562////////////////////////////////////////////////////////////////////////////////
563///Draw poly-line in user coordinates.
564
566{
567 if (fLocked) return;
568
570
571 glBegin(GL_LINE_STRIP);
572
573 for (Int_t i = 0; i < n; ++i)
574 glVertex2d(x[i], y[i]);
575
576 if (fIsHollowArea) {
577 glVertex2d(x[0], y[0]);
579 }
580 glEnd();
581
582 if (gVirtualX->GetLineWidth() > lineWidthTS) {
583 Double_t pointSize = gVirtualX->GetLineWidth();
589 glBegin(GL_POINTS);
590
591 for (Int_t i = 0; i < n; ++i)
592 glVertex2d(x[i], y[i]);
593
594 glEnd();
595 glPointSize(1.f);
596 }
597}
598
599////////////////////////////////////////////////////////////////////////////////
600///Never called?
601
603{
604 if (fLocked) return;
605
607
608 glBegin(GL_LINE_STRIP);
609
610 for (Int_t i = 0; i < n; ++i)
611 glVertex2f(x[i], y[i]);
612
613 if (fIsHollowArea) {
614 glVertex2f(x[0], y[0]);
616 }
617
618 glEnd();
619}
620
621////////////////////////////////////////////////////////////////////////////////
622///Poly line in NDC.
623
625{
626 if (fLocked) return;
627
629 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
630 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
631 const Double_t x1 = gPad->GetX1(), y1 = gPad->GetY1();
632
633 glBegin(GL_LINE_STRIP);
634
635 for (Int_t i = 0; i < n; ++i)
636 glVertex2d(x1 + u[i] * xRange, y1 + v[i] * yRange);
637
638 glEnd();
639}
640
641namespace {
642
643//Aux. function.
644template<class ValueType>
645void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst);
646
647}
648
649////////////////////////////////////////////////////////////////////////////////
650///Poly-marker.
651
653{
654 if (fLocked) return;
655
658}
659
660////////////////////////////////////////////////////////////////////////////////
661///Poly-marker.
662
664{
665 if (fLocked) return;
666
669}
670
671////////////////////////////////////////////////////////////////////////////////
672///Poly-marker.
673
675{
676 if (fLocked) return;
677
680 //
681 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
682 //
684 //
686
687 Float_t rgba[4] = {};
688 Rgl::Pad::ExtractRGBA(gVirtualX->GetMarkerColor(), rgba);
691
692 const Width_t w = TMath::Max(1, Int_t(TAttMarker::GetMarkerLineWidth(gVirtualX->GetMarkerStyle())));
694
695 const TPoint *xy = &fPoly[0];
697 const UInt_t n = UInt_t(fPoly.size());
698 switch (markerStyle) {
699 case kDot:
701 break;
702 case kPlus:
704 break;
705 case kStar:
706 case 31:
708 break;
709 case kCircle:
710 case kOpenCircle:
712 break;
713 case kMultiply:
714 fMarker.DrawX(n, xy);
715 break;
716 case kFullDotSmall://"Full dot small"
718 break;
719 case kFullDotMedium:
721 break;
722 case kFullDotLarge:
723 case kFullCircle:
725 break;
726 case kFullSquare:
728 break;
729 case kFullTriangleUp:
731 break;
734 break;
735 case kOpenSquare:
739 break;
740 case kOpenTriangleUp:
744 break;
745 case kOpenDiamond:
747 break;
748 case kOpenCross:
750 break;
751 case kFullStar:
753 break;
754 case kOpenStar:
756 break;
759 break;
760 case kFullDiamond:
762 break;
763 case kFullCross:
765 break;
768 break;
771 break;
774 break;
775 case kOctagonCross:
777 break;
780 break;
783 break;
786 break;
789 break;
792 break;
795 break;
798 break;
799 case kOpenCrossX:
801 break;
802 case kFullCrossX:
804 break;
805 case kFourSquaresX:
807 break;
808 case kFourSquaresPlus:
810 break;
811 }
812
815 glLineWidth(1.f);
816}
817
818////////////////////////////////////////////////////////////////////////////////
819
820template<class Char>
822{
824
826 //
827 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
828 //
830
831 Float_t rgba[4] = {};
832 Rgl::Pad::ExtractRGBA(gVirtualX->GetTextColor(), rgba);
834
835 //10 is the first valid font index.
836 //20 is FreeSerifBold, as in TTF.cxx and in TGLFontManager.cxx.
837 //shift - is the shift to access "extended" fonts.
839
840 Int_t fontIndex = TMath::Max(Short_t(10), gVirtualX->GetTextFont());
841 if (fontIndex / 10 + shift > TGLFontManager::GetFontFileArray()->GetEntries())
842 fontIndex = 20 + shift * 10;
843 else
844 fontIndex += shift * 10;
845
846 fFM.RegisterFont(TMath::Max(Int_t(gVirtualX->GetTextSize()) - 1, 10),//kTexture does not work if size < 10.
849 fF.PreRender();
850
851 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
852 fF.Render(text, gPad->XtoPixel(x), padH - gPad->YtoPixel(y), GetTextAngle(), GetTextMagnitude());
853
854 fF.PostRender();
856
858}
859
860////////////////////////////////////////////////////////////////////////////////
861///Draw text. This operation is especially
862///dangerous if in locked state -
863///ftgl will assert on zero texture size
864///(which is result of bad GL context).
865
867{
868 if (fLocked) return;
869
870 if (!gVirtualX->GetTextSize())
871 return;
872
874}
875
876////////////////////////////////////////////////////////////////////////////////
877///Draw text. This operation is especially
878///dangerous if in locked state -
879///ftgl will assert on zero texture size
880///(which is result of bad GL context).
881
883{
884 if (fLocked) return;
885
886 if (!gVirtualX->GetTextSize())
887 return;
888
890}
891
892////////////////////////////////////////////////////////////////////////////////
893///Draw text in NDC. This operation is especially
894///dangerous if in locked state -
895///ftgl will assert on zero texture size
896///(which is result of bad GL context).
897
899{
900 if (fLocked) return;
901
902 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
903 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
904 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
905}
906
907////////////////////////////////////////////////////////////////////////////////
908///Draw text in NDC. This operation is especially
909///dangerous if in locked state -
910///ftgl will assert on zero texture size
911///(which is result of bad GL context).
912
914{
915 if (fLocked) return;
916
917 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
918 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
919 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
920}
921
922////////////////////////////////////////////////////////////////////////////////
923///Save the projection matrix.
924///Attention! GL_PROJECTION will become the current matrix
925///after this call!
926
932
933////////////////////////////////////////////////////////////////////////////////
934///Restore the projection matrix.
935///Attention! GL_PROJECTION will become the current matrix
936///after this call!
937
943
944////////////////////////////////////////////////////////////////////////////////
945///Save the modelview matrix.
946///Attention! GL_MODELVIEW will become the current matrix
947///after this call!
948
954
955////////////////////////////////////////////////////////////////////////////////
956///Restore the modelview matrix.
957///Attention! GL_MODELVIEW will become the current matrix
958///after this call!
959
965
966////////////////////////////////////////////////////////////////////////////////
967///Extract and save the current viewport.
968
973
974////////////////////////////////////////////////////////////////////////////////
975///Restore the saved viewport.
976
978{
979 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
980}
981
982////////////////////////////////////////////////////////////////////////////////
983/// Using TImage save frame-buffer contents as a picture.
984
985void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
986{
987 TVirtualPad *canvas = (TVirtualPad *)pad->GetCanvas();
988 if (!canvas)
989 return;
990
991 gROOT->ProcessLine(Form("((TCanvas *)0x%zx)->Flush();", (size_t)canvas));
992
993 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
996 //In case GL_BGRA is not in gl.h (old windows' gl) - comment/uncomment lines.
997 //glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_BGRA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
998 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
999
1000 std::unique_ptr<TImage> image(TImage::Create());
1001 if (!image.get()) {
1002 ::Error("TGLPadPainter::SaveImage", "TImage creation failed");
1003 return;
1004 }
1005
1006 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
1007 UInt_t *argb = image->GetArgbArray();
1008
1009 if (!argb) {
1010 ::Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
1011 return;
1012 }
1013
1014 const Int_t nLines = canvas->GetWh();
1015 const Int_t nPixels = canvas->GetWw();
1016
1017 for (Int_t i = 0; i < nLines; ++i) {
1018 Int_t base = (nLines - 1 - i) * nPixels;
1019 for (Int_t j = 0; j < nPixels; ++j, ++base) {
1020 //Uncomment/comment if you don't have GL_BGRA.
1021
1022 const UInt_t pix = buff[base];
1023 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
1024 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
1025
1026 //argb[i * nPixels + j] = buff[base];
1027 argb[i * nPixels + j] = bgra;
1028 }
1029 }
1030
1031 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
1032}
1033
1034////////////////////////////////////////////////////////////////////////////////
1035
1038{
1039 if (fLocked)
1040 return;
1041
1042 if (!pixelData) {
1043 //I'd prefer an assert.
1044 ::Error("TGLPadPainter::DrawPixels", "pixel data is null");
1045 return;
1046 }
1047
1048 if (std::numeric_limits<UInt_t>::digits >= 32) {
1049 //TASImage uses bit 31 as ...
1050 //alpha channel flag! FUUUUUUUUUUUUU ..... !!!
1051 CLRBIT(width, 31);
1052 CLRBIT(height, 31);
1053 }
1054
1055 if (!width) {
1056 //Assert is better.
1057 ::Error("TGLPadPainter::DrawPixels", "invalid width");
1058 return;
1059 }
1060
1061 if (!height) {
1062 //Assert is better.
1063 ::Error("TGLPadPainter::DrawPixels", "invalid height");
1064 return;
1065 }
1066
1067 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
1068 //TASImage passes pixel coordinates in pad's pixmap coordinate space.
1069 //While glRasterPosX said to work with 'window' coordinates,
1070 //that's a lie :) it does not :)
1071
1072 const Double_t rasterX = Double_t(dstX) / (pad->GetAbsWNDC() * pad->GetWw()) *
1073 (pad->GetX2() - pad->GetX1()) + pad->GetX1();
1074
1075 const Double_t yRange = pad->GetY2() - pad->GetY1();
1076 const Double_t rasterY = yRange - Double_t(dstY + height) / (pad->GetAbsHNDC() * pad->GetWh()) * yRange +
1077 pad->GetY1();
1078
1079 GLdouble oldPos[4] = {};
1080 //Save the previous raster pos.
1082
1084 //Stupid asimage provides us upside-down image.
1085 std::vector<unsigned char> upsideDownImage(4 * width * height);
1086 const unsigned char *srcLine = pixelData + 4 * width * (height - 1);
1087 unsigned char *dstLine = &upsideDownImage[0];
1088 for (UInt_t i = 0; i < height; ++i, srcLine -= 4 * width, dstLine += 4 * width)
1089 std::copy(srcLine, srcLine + 4 * width, dstLine);
1090
1091 if (enableBlending) {
1094 }
1095
1097
1098 if (enableBlending)
1100
1101 //Restore raster pos.
1102 glRasterPos2d(oldPos[0], oldPos[1]);
1103 } else
1104 ::Error("TGLPadPainter::DrawPixels", "no pad found to draw");
1105}
1106
1107//Aux. functions - gradient and solid fill of arbitrary area.
1108
1109////////////////////////////////////////////////////////////////////////////////
1110///At the moment I assume both linear and radial gradients will work the same way -
1111///using a stencil buffer and some big rectangle(s) to fill with a gradient.
1112///Thus I have a 'common' part - the part responsible for a stencil test.
1113
1115{
1116 assert(n > 2 && "DrawPolygonWithGradient, invalid number of points");
1117 assert(x != nullptr && "DrawPolygonWithGradient, parameter 'x' is null");
1118 assert(y != nullptr && "DrawPolygonWithGradient, parameter 'y' is null");
1119
1120 assert(dynamic_cast<TColorGradient *>(gROOT->GetColor(gVirtualX->GetFillColor())) != nullptr &&
1121 "DrawPolygonWithGradient, the current fill color is not a gradient fill");
1122 const TColorGradient * const grad =
1123 dynamic_cast<TColorGradient *>(gROOT->GetColor(gVirtualX->GetFillColor()));
1124
1125 if (fLocked)
1126 return;
1127
1128 //Now, some magic!
1130
1131 //TODO: check that the state is restored back correctly after
1132 // we done with a gradient.
1133 //TODO: make sure that we have glDepthMask set to false in general!
1135
1136 glStencilFunc(GL_NEVER, 1, 0xFF);
1137 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);// draw 1s on test fail (always)
1138 //Draw stencil pattern
1139 glStencilMask(0xFF);
1141
1142 //Draw our polygon into the stencil buffer:
1143 DrawTesselation(n, x, y);
1144
1146 glStencilMask(0x00);
1147 //Draw where stencil's value is 0
1148 glStencilFunc(GL_EQUAL, 0, 0xFF);
1149 //Draw only where stencil's value is 1
1150 glStencilFunc(GL_EQUAL, 1, 0xFF);
1151
1152 //At the moment radial gradient is derived from linear - it was convenient
1153 //at some point, but in fact it was a bad idea. And now I have to
1154 //first check radial gradient.
1155 //TODO: TRadialGradient must inherit TColorGradient directly.
1156 const TRadialGradient * const rGrad = dynamic_cast<const TRadialGradient *>(grad);
1157 if (rGrad)
1158 DrawGradient(rGrad, n, x, y);
1159 else {
1160 const TLinearGradient * const lGrad = dynamic_cast<const TLinearGradient *>(grad);
1161 assert(lGrad != nullptr && "DrawPolygonWithGradient, unknown gradient type");
1162 DrawGradient(lGrad, n, x, y);
1163 }
1164}
1165
1166////////////////////////////////////////////////////////////////////////////////
1167
1169 const Double_t *xs, const Double_t *ys)
1170{
1171 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1172 assert(nPoints > 2 && "DrawGradient, invalid number of points");
1173 assert(xs != nullptr && "DrawGradient, parameter 'xs' is null");
1174 assert(ys != nullptr && "DrawGradient, parameter 'ys' is null");
1175
1177 ::Warning("TGLPadPainter::DrawGradient",
1178 "extended radial gradient is not supported");//yet?
1179 return;
1180 }
1181
1182 //TODO: check the polygon's bbox!
1183 const auto &bbox = Rgl::Pad::FindBoundingRect(nPoints, xs, ys);
1184 //
1185 auto center = grad->GetCenter();
1186 auto radius = grad->GetRadius();
1187 //Adjust the center and radius depending on coordinate mode.
1189 radius *= TMath::Max(bbox.fWidth, bbox.fHeight);
1190 center.fX = bbox.fWidth * center.fX + bbox.fXMin;
1191 center.fY = bbox.fHeight * center.fY + bbox.fYMin;
1192 } else {
1193 const auto w = gPad->GetX2() - gPad->GetX1();
1194 const auto h = gPad->GetY2() - gPad->GetY1();
1195
1196 radius *= TMath::Max(w, h);
1197 center.fX *= w;
1198 center.fY *= h;
1199 }
1200 //Now for the gradient fill we switch into pixel coordinates:
1201 const auto pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1202 const auto pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1203 //
1206 //A new ortho projection:
1209 //
1210 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1211 //
1213 center.fX = gPad->XtoPixel(center.fX);
1214 center.fY = pixelH - gPad->YtoPixel(center.fY);
1215
1216 Double_t maxR = 0.;
1217 {
1218 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1219 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1220 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1221 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1222 //Get the longest distance from the center to the bounding box vertices
1223 //(this will be the maximum possible radius):
1224 const Double_t maxDistX = TMath::Max(TMath::Abs(center.fX - xMin),
1225 TMath::Abs(center.fX - xMax));
1226 const Double_t maxDistY = TMath::Max(TMath::Abs(center.fY - yMin),
1227 TMath::Abs(center.fY - yMax));
1229 }
1230
1231 //If gradient 'stops inside the polygon', we use
1232 //the solid fill for the area outside of radial gradient:
1233 const Bool_t solidFillAfter = maxR > radius;
1234 //We emulate a radial gradient using triangles and linear gradient:
1235 //TODO: Can be something smarter? (btw even 100 seems to be enough)
1236 const UInt_t nSlices = 500;
1237
1238 const auto nColors = grad->GetNumberOfSteps();
1239 //+1 - the strip from the last color's position to radius,
1240 //and (probably) + 1 for solidFillAfter.
1241 const auto nCircles = nColors + 1 + solidFillAfter;
1242
1243 //TODO: can locations be outside of [0., 1.] ???
1244 //at the moment I assume the answer is NO, NEVER.
1245 const auto locations = grad->GetColorPositions();
1246 // * 2 below == x,y
1247 std::vector<Double_t> circles(nSlices * nCircles * 2);
1248 const Double_t angle = TMath::TwoPi() / nSlices;
1249
1250 //"Main" circles (for colors at locations[i]).
1251 for (UInt_t i = 0; i < nColors; ++i) {
1252 const auto circle = &circles[i * nSlices * 2];
1253 //TODO: either check locations here or somewhere else.
1254 const auto r = radius * locations[i];
1255 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1256 circle[j] = center.fX + r * TMath::Cos(angle * j);
1257 circle[j + 1] = center.fY + r * TMath::Sin(angle * j);
1258 }
1259 //The "closing" vertices:
1260 circle[(nSlices - 1) * 2] = circle[0];
1261 circle[(nSlices - 1) * 2 + 1] = circle[1];
1262 }
1263
1264 {
1265 //The strip between lastPos and radius:
1266 const auto circle = &circles[nColors * nSlices * 2];
1267 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1268 circle[j] = center.fX + radius * TMath::Cos(angle * j);
1269 circle[j + 1] = center.fY + radius * TMath::Sin(angle * j);
1270 }
1271
1272 circle[(nSlices - 1) * 2] = circle[0];
1273 circle[(nSlices - 1) * 2 + 1] = circle[1];
1274 }
1275
1276 if (solidFillAfter) {
1277 //The strip after the radius:
1278 const auto circle = &circles[(nCircles - 1) * nSlices * 2];
1279 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1280 circle[j] = center.fX + maxR * TMath::Cos(angle * j);
1281 circle[j + 1] = center.fY + maxR * TMath::Sin(angle * j);
1282 }
1283
1284 circle[(nSlices - 1) * 2] = circle[0];
1285 circle[(nSlices - 1) * 2 + 1] = circle[1];
1286 }
1287
1288 //Now we draw:
1289 //1) triangle fan in the center (from center to the locations[1],
1290 // with a solid fill).
1291 //2) quad strips for colors.
1292 //3) additional quad strip from the lastLocation to the radius
1293 //4) additional quad strip (if any) from the radius to maxR.
1294
1295 //RGBA values:
1296 const auto rgba = grad->GetColors();
1297
1299 //TODO?
1301
1302 //Probably a degenerated case. Maybe not.
1305 glVertex2d(center.fX, center.fY);
1306
1307 for (UInt_t i = 0, e = nSlices * 2; i < e; i += 2)
1308 glVertex2dv(&circles[i]);
1309
1310 glEnd();
1311
1312 //No auto for circles, explicit types to have const Double_t * const, not Duble_t * const.
1313 for (UInt_t i = 0; i < nColors - 1; ++i) {
1314 const Double_t * const inner = &circles[i * nSlices * 2];
1315 const auto innerRGBA = rgba + i * 4;
1316 const auto outerRGBA = rgba + (i + 1) * 4;
1317 const Double_t * const outer = &circles[(i + 1) * nSlices * 2];
1318
1320 }
1321
1322 //Probably degenerated strip.
1323 {
1324 const Double_t * const inner = &circles[nSlices * (nColors - 1) * 2];
1325 const auto solidRGBA = rgba + (nColors - 1) * 4;
1326 const Double_t * const outer = &circles[nSlices * nColors * 2];
1327
1329 }
1330
1331 if (solidFillAfter) {
1332 const Double_t * const inner = &circles[nSlices * nColors * 2];
1333 const auto solidRGBA = rgba + (nColors - 1) * 4;
1334 const Double_t * const outer = &circles[nSlices * (nColors + 1) * 2];
1335
1337 }
1338
1341}
1342
1343////////////////////////////////////////////////////////////////////////////////
1344
1346 const Double_t *x, const Double_t *y)
1347{
1348 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1349 assert(n > 2 && "DrawGradient, invalid number of points");
1350 assert(x != nullptr && "DrawGradient, parameter 'x' is null");
1351 assert(y != nullptr && "DrawGradient, parameter 'y' is null");
1352
1353 //Now we fill the whole scene with one big rectangle
1354 //(group of rectangles) with a gradient fill using
1355 //stencil test.
1356
1357 //Find a bounding rect.
1358 const auto &bbox = Rgl::Pad::FindBoundingRect(n, x, y);
1359 //TODO: check the bbox??
1360
1361 //For the gradient fill we switch into the
1362 //pixel coordinates.
1365
1366 //A new ortho projection:
1369
1370 const Double_t pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1371 const Double_t pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1372 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1373
1374 //A new modelview:
1377 //
1378 TColorGradient::Point start = grad->GetStart();
1379 TColorGradient::Point end = grad->GetEnd();
1380
1381 //Change gradient coordinates from 'NDC' to pad coords:
1383 {
1384 const Double_t w = gPad->GetX2() - gPad->GetX1();
1385 const Double_t h = gPad->GetY2() - gPad->GetY1();
1386
1387 start.fX = start.fX * w;
1388 start.fY = start.fY * h;
1389 end.fX = end.fX * w;
1390 end.fY = end.fY * h;
1391 } else {
1392 start.fX = start.fX * bbox.fWidth + bbox.fXMin;
1393 start.fY = start.fY * bbox.fHeight + bbox.fYMin;
1394 end.fX = end.fX * bbox.fWidth + bbox.fXMin;
1395 end.fY = end.fY * bbox.fHeight + bbox.fYMin;
1396 }
1397
1398 //TODO: with a radial fill we'll have to extract the code
1399 // below into the separate function/and have additional function
1400 // for a radial gradient.
1401 //Now from pad to pixels:
1402 start.fX = gPad->XtoPixel(start.fX);
1403 start.fY = pixelH - gPad->YtoPixel(start.fY);
1404 end.fX = gPad->XtoPixel(end.fX);
1405 end.fY = pixelH - gPad->YtoPixel(end.fY);
1406 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1407 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1408 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1409 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1410 //
1411
1412 //TODO: check all calculations!
1413
1414 //Get the longest distance from the start point to the bounding box vertices:
1415 const Double_t maxDistX = TMath::Max(TMath::Abs(start.fX - xMin), TMath::Abs(start.fX - xMax));
1416 const Double_t maxDistY = TMath::Max(TMath::Abs(start.fY - yMin), TMath::Abs(start.fY - yMax));
1417
1418 const Double_t startEndLength = TMath::Sqrt((end.fX - start.fX) * (end.fX - start.fX) +
1419 (end.fY - start.fY) * (end.fY - start.fY));
1422
1423 //Boxes with a gradients to emulate gradient fill with many colors:
1424 const Double_t * const colorPositions = grad->GetColorPositions();
1425 std::vector<Double_t> gradBoxes(grad->GetNumberOfSteps() + 2);
1426 gradBoxes[0] = start.fY - h;
1427 for (unsigned i = 1; i <= grad->GetNumberOfSteps(); ++i)
1428 gradBoxes[i] = startEndLength * colorPositions[i - 1] + start.fY;
1429
1430 gradBoxes[grad->GetNumberOfSteps() + 1] = start.fY + h;
1431
1432 //Rotation angle - gradient's axis:
1433 Double_t angle = TMath::ACos((startEndLength * (end.fY - start.fY)) /
1435 if (end.fX > start.fX)
1436 angle *= -1;
1437
1438 glTranslated(start.fX, start.fY, 0.);
1439 glRotated(angle, 0., 0., 1.);
1440 glTranslated(-start.fX, -start.fY, 0.);
1441 //
1442 const Double_t * const rgba = grad->GetColors();
1443
1444 const unsigned nEdges = gradBoxes.size();
1445 const unsigned nColors = grad->GetNumberOfSteps();
1446 const Double_t xLeft = start.fX - h, xRight = start.fX + h;
1447
1449 //TODO?
1451
1454 rgba + (nColors - 1) * 4, rgba + (nColors - 1) * 4);
1455
1456 for (unsigned i = 1; i < nEdges - 2; ++i)
1458 xRight, rgba + (i - 1) * 4, rgba + i * 4);
1459
1462}
1463
1464////////////////////////////////////////////////////////////////////////////////
1465
1467{
1468 assert(n > 2 && "DrawTesselation, invalid number of points");
1469 assert(x != nullptr && "DrawTesselation, parameter 'x' is null");
1470 assert(y != nullptr && "DrawTesselation, parameter 'y' is null");
1471
1472 //Data for a tesselator:
1473 fVs.resize(n * 3);
1474
1475 for (Int_t i = 0; i < n; ++i) {
1476 fVs[i * 3] = x[i];
1477 fVs[i * 3 + 1] = y[i];
1478 fVs[i * 3 + 2] = 0.;
1479 }
1480
1481 //TODO: A very primitive way to tesselate - check what
1482 //kind of polygons we can really have from TPad/TCanvas.
1484 gluBeginPolygon(t);
1486
1487 for (Int_t i = 0; i < n; ++i)
1488 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
1489
1490 gluEndPolygon(t);
1491}
1492
1493
1494//Aux. functions.
1495namespace {
1496
1497template<class ValueType>
1498void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst)
1499{
1500 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
1501
1502 dst.resize(n);
1503 for (Int_t i = 0; i < n; ++i) {
1504 dst[i].fX = gPad->XtoPixel(x[i]);
1505 dst[i].fY = padH - gPad->YtoPixel(y[i]);
1506 }
1507}
1508
1509}
1510
#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
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:66
@ kStar
Definition TAttMarker.h:56
@ kFullDotLarge
Definition TAttMarker.h:57
@ kFullDoubleDiamond
Definition TAttMarker.h:66
@ kOpenFourTrianglesX
Definition TAttMarker.h:65
@ kOpenSquare
Definition TAttMarker.h:59
@ kFullThreeTriangles
Definition TAttMarker.h:64
@ kOpenTriangleUp
Definition TAttMarker.h:60
@ kFourSquaresPlus
Definition TAttMarker.h:69
@ kFullDotSmall
Definition TAttMarker.h:57
@ kFullDotMedium
Definition TAttMarker.h:57
@ kOpenTriangleDown
Definition TAttMarker.h:61
@ kOpenThreeTriangles
Definition TAttMarker.h:63
@ kFullCrossX
Definition TAttMarker.h:68
@ kFullFourTrianglesX
Definition TAttMarker.h:65
@ kFullTriangleDown
Definition TAttMarker.h:59
@ kCircle
Definition TAttMarker.h:56
@ kOpenCrossX
Definition TAttMarker.h:68
@ kFullFourTrianglesPlus
Definition TAttMarker.h:67
@ kFullSquare
Definition TAttMarker.h:58
@ kOpenSquareDiagonal
Definition TAttMarker.h:63
@ kFullStar
Definition TAttMarker.h:61
@ kOpenDiamond
Definition TAttMarker.h:60
@ kFullTriangleUp
Definition TAttMarker.h:58
@ kOpenDiamondCross
Definition TAttMarker.h:62
@ kOpenFourTrianglesPlus
Definition TAttMarker.h:67
@ kMultiply
Definition TAttMarker.h:56
@ kPlus
Definition TAttMarker.h:56
@ kOctagonCross
Definition TAttMarker.h:64
@ kFullCircle
Definition TAttMarker.h:58
@ kDot
Definition TAttMarker.h:56
@ kOpenCross
Definition TAttMarker.h:60
@ kFourSquaresX
Definition TAttMarker.h:68
@ kOpenCircle
Definition TAttMarker.h:59
@ kFullCross
Definition TAttMarker.h:62
@ kOpenStar
Definition TAttMarker.h:61
@ kFullDiamond
Definition TAttMarker.h:62
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.
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.
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
Not required at the moment.
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 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.
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.
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.
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.
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