Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGLPadPainter.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Timur Pocheptsov 06/05/2009
3
4/*************************************************************************
5 * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <stdexcept>
13#include <cassert>
14#include <limits>
15#include <memory>
16#include <vector>
17
18#include "TAttMarker.h"
19#include "TVirtualX.h"
20#include "TError.h"
21#include "TImage.h"
22#include "TROOT.h"
23#include "TPad.h"
24#include "TCanvas.h"
25
26#include "TColorGradient.h"
27#include "TGLPadPainter.h"
28#include "TGLIncludes.h"
29#include "TGLUtil.h"
30#include "TMath.h"
31
32#include <glad/gl.h>
33
34namespace {
35
36////////////////////////////////////////////////////////////////////////////////
37///Not a bad idea to assert on gVirtualX != nullptr
38
40{
41 return dynamic_cast<TColorGradient *>(gROOT->GetColor(fillColorIndex));
42}
43
44}
45
46/** \class TGLPadPainter
47\ingroup opengl
48"Delegating" part of TGLPadPainter. Line/fill/etc. attributes can be
49set inside TPad, but not only there:
50many of them are set by base sub-objects of 2d primitives
51(2d primitives usually inherit TAttLine or TAttFill etc.). And these sub-objects
52call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
53it will be mess - at any moment I do not know, where to take line attribute - from
54gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
55*/
56
57
58////////////////////////////////////////////////////////////////////////////////
59
61 : fIsHollowArea(kFALSE),
62 fLocked(kTRUE)
63{
64 fVp[0] = fVp[1] = fVp[2] = fVp[3] = 0;
65 fWinContext = 0;
66}
67
68
69////////////////////////////////////////////////////////////////////////////////
70///Delegate to gVirtualX.
71
73{
74 // does not work this way
75 gVirtualX->SetOpacityW(fWinContext, percent);
76}
77
78////////////////////////////////////////////////////////////////////////////////
79///Delegate to gVirtualX.
80
82{
83 return gVirtualX->GetTextMagnitude();
84}
85
86////////////////////////////////////////////////////////////////////////////////
87/// Select pad where current painting will be performed
88
90{
91 // GL painter does not use proper id for sub-pads (see CreateDrawable)
92 // so one always use canvas ID to execute TVirtualX-specific commands
93 if (!fWinContext)
94 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
95}
96
97////////////////////////////////////////////////////////////////////////////////
98/// Set fill attributes
99
101{
103
105
106 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
107 if (fWinContext && gVirtualX)
108 gVirtualX->SetAttFill(fWinContext, att);
109}
110
111////////////////////////////////////////////////////////////////////////////////
112/// Set line attributes
113
115{
117
118 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
119 if (fWinContext && gVirtualX)
120 gVirtualX->SetAttLine(fWinContext, att);
121}
122
123////////////////////////////////////////////////////////////////////////////////
124/// Set marker attributes
125
127{
129
130 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
131 if (fWinContext && gVirtualX)
132 gVirtualX->SetAttMarker(fWinContext, att);
133}
134
135/*
136"Pixmap" part of TGLPadPainter.
137*/
138
139////////////////////////////////////////////////////////////////////////////////
140///Not required at the moment.
141
143{
144 // return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
145 return 0;
146}
147
148////////////////////////////////////////////////////////////////////////////////
149/// Resize a gVirtualX Pixmap.
150
152{
153 return gVirtualX->ResizePixmap(device, w, h);
154}
155
156////////////////////////////////////////////////////////////////////////////////
157/// Do nothing, sub-pads not cleared in GL
158
162
163////////////////////////////////////////////////////////////////////////////////
164/// Clear specified window - calling gVirtualX->ClearWindowW
165
167{
168 auto ctxt = gVirtualX->GetWindowContext(device);
169 if (ctxt)
170 gVirtualX->ClearWindowW(ctxt);
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Returns true when cocoa backend is used
175
177{
178 return gVirtualX->InheritsFrom("TGCocoa");
179}
180
181////////////////////////////////////////////////////////////////////////////////
182///Not required at the moment.
183
184void TGLPadPainter::CopyDrawable(Int_t /* device */, Int_t /* px */, Int_t /* py */)
185{
186 // gVirtualX->CopyPixmapW(fWinContext, device, px, py);
187}
188
189////////////////////////////////////////////////////////////////////////////////
190///Not required at the moment.
191
193{
194 // gVirtualX->SelectWindow(device);
195 // gVirtualX->ClosePixmap();
196 fWinContext = 0;
197}
198
199////////////////////////////////////////////////////////////////////////////////
200///For gVirtualX this means select pixmap (or window)
201///and all subsequent drawings will go into
202///this pixmap. For OpenGL this means the change of
203///coordinate system and viewport.
204
206{
207 auto pad = dynamic_cast<TPad *>(gPad);
208 if (!fWinContext && pad)
209 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
210
211 if (fLocked)
212 return;
213
214 if (pad) {
215 // GL painter does not use proper id for sub-pads (see CreateDrawable)
216 // so one always use canvas ID to execute TVirtualX-specific commands
217 Int_t px = 0, py = 0;
218
219 pad->XYtoAbsPixel(pad->GetX1(), pad->GetY1(), px, py);
220
221 py = gPad->GetWh() - py;
222 //
225
226 glViewport(GLint(px * scale), GLint(py * scale),
227 GLsizei(gPad->GetWw() * pad->GetAbsWNDC() * scale),
228 GLsizei(gPad->GetWh() * pad->GetAbsHNDC() * scale));
229
232 glOrtho(pad->GetX1(), pad->GetX2(), pad->GetY1(), pad->GetY2(), -10., 10.);
233
236 glTranslated(0., 0., -1.);
237 } else {
238 ::Error("TGLPadPainter::SelectDrawable",
239 "function was called not from TPad or TCanvas code\n");
240 throw std::runtime_error("");
241 }
242}
243
244////////////////////////////////////////////////////////////////////////////////
245/// Call low-level update of selected drawable, redirect to gVirtualX.
246
248{
249 if (fWinContext)
250 gVirtualX->UpdateWindowW(fWinContext, mode);
251}
252
253
254////////////////////////////////////////////////////////////////////////////////
255/// Set drawing mode for specified device
256
258{
259 auto ctxt = fWinContext;
260 if (device)
261 ctxt = gVirtualX->GetWindowContext(device);
262 if (ctxt)
263 gVirtualX->SetDrawModeW(ctxt, (TVirtualX::EDrawMode) mode);
264}
265
266////////////////////////////////////////////////////////////////////////////////
267///Init gl-pad painter:
268///1. 2D painter does not use depth test, should not modify
269/// depth-buffer content (except initial cleanup).
270///2. Disable cull face.
271///3. Disable lighting.
272///4. Set viewport (to the whole canvas area).
273///5. Set camera.
274///6. Unlock painter.
275
277{
278 static bool gl_init = false;
279 if (!gl_init) {
281 if (version == 0)
282 Warning("TGLPadPainter::InitPainter", "GL initalization failed.");
283 else if (gDebug > 0)
284 Info("TGLPadPainter::InitPainter", "GL initalization successful.");
285 gl_init = true;
286 }
290
291 //Clear the buffer
292 glViewport(0, 0, GLsizei(gPad->GetWw()), GLsizei(gPad->GetWh()));
293
295 glClearColor(1.,1.,1.,1.);
298
301
302 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
303
306 glTranslated(0., 0., -1.);
307
308 fLocked = kFALSE;
309}
310
311////////////////////////////////////////////////////////////////////////////////
312///When TPad::Range for gPad is called, projection
313///must be changed in OpenGL.
314
316{
317 if (fLocked) return;
318
321
322 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
323
325}
326
327////////////////////////////////////////////////////////////////////////////////
328///Locked state of painter means, that
329///GL context can be invalid, so no GL calls
330///can be executed.
331
333{
334 if (fLocked) return;
335
336 glFinish();
337 fLocked = kTRUE;
338}
339
340/*
3412D primitives.
342*/
343
345
346////////////////////////////////////////////////////////////////////////////////
347///Draw line segment.
348
350{
351 if (fLocked) {
352 //GL pad painter can be called in non-standard situation:
353 //not from TPad::Paint, but
354 //from TView3D::ExecuteRotateView. This means in fact,
355 //that TView3D wants to draw itself in a XOR mode, via
356 //gVirtualX.
357 // TODO: only here set line attributes to virtual x
358 if (IsInvertMode())
359 gVirtualX->DrawLineW(fWinContext,
360 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
361 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2));
362
363 return;
364 }
365
367
368 glBegin(GL_LINES);
369 glVertex2d(x1, y1);
370 glVertex2d(x2, y2);
371 glEnd();
372
374 Double_t pointSize = GetAttLine().GetLineWidth();
380 glBegin(GL_POINTS);
381
382 glVertex2d(x1, y1);
383 glVertex2d(x2, y2);
384
385 glEnd();
386 glPointSize(1.f);
387 }
388
389}
390
391////////////////////////////////////////////////////////////////////////////////
392///Draw line segment in NDC coordinates.
393
395{
396 if (fLocked) {
397 // this code used when crosshair cursor is drawn or interactive objects move
398 if (IsInvertMode())
399 gVirtualX->DrawLineW(fWinContext,
400 gPad->UtoAbsPixel(u1), gPad->VtoAbsPixel(v1),
401 gPad->UtoAbsPixel(u2), gPad->VtoAbsPixel(v2));
402 return;
403 }
404
406 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
407 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
408
409 glBegin(GL_LINES);
410 glVertex2d(gPad->GetX1() + u1 * xRange, gPad->GetY1() + v1 * yRange);
411 glVertex2d(gPad->GetX1() + u2 * xRange, gPad->GetY1() + v2 * yRange);
412 glEnd();
413}
414
415////////////////////////////////////////////////////////////////////////////////
416///Draw filled or hollow box.
417
419{
420 if (fLocked) {
421 //GL pad painter can be called in non-standard situation:
422 //not from TPad::Paint, but
423 //from TView3D::ExecuteRotateView. This means in fact,
424 //that TView3D wants to draw itself in a XOR mode, via
425 //gVirtualX.
426 // TODO: only here set line attributes to virtual x
427 if (IsInvertMode())
428 gVirtualX->DrawBoxW(fWinContext,
429 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
430 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2),
432 return;
433 }
434
436 Double_t xs[] = {x1, x2, x2, x1};
437 Double_t ys[] = {y1, y1, y2, y2};
439 return;
440 }
441
442 if (mode == kHollow) {
444 glBegin(GL_LINE_LOOP);
445 glVertex2d(x1, y1);
446 glVertex2d(x2, y1);
447 glVertex2d(x2, y2);
448 glVertex2d(x1, y2);
449 glEnd();
450 } else {
451 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE, &fGlFillAtt);//Set filling parameters.
452 glRectd(x1, y1, x2, y2);
453 }
454}
455
456////////////////////////////////////////////////////////////////////////////////
457///Draw tesselated polygon (probably, outline only).
458
460{
461 assert(x != nullptr && "DrawFillArea, parameter 'x' is null");
462 assert(y != nullptr && "DrawFillArea, parameter 'y' is null");
463
464 if (fLocked)
465 return;
466
467 if (n < 3) {
468 ::Error("TGLPadPainter::DrawFillArea",
469 "invalid number of points in a polygon");
470 return;
471 }
472
474 return DrawPolygonWithGradient(n, x, y);
475
476 if (fFullyTransparent) {
478 return DrawPolyLine(n, x, y);
479 }
480
482 DrawTesselation(n, x, y);
483}
484
485////////////////////////////////////////////////////////////////////////////////
486///Draw tesselated polygon (never called, probably, since TPad::PaintFillArea for floats
487///is deprecated).
488
490{
491 if (fLocked) return;
492
493 if (fFullyTransparent) {
495 return DrawPolyLine(n, x, y);
496 }
497
498 fVs.resize(n * 3);
499
500 for (Int_t i = 0; i < n; ++i) {
501 fVs[i * 3] = x[i];
502 fVs[i * 3 + 1] = y[i];
503 }
504
506
510
511 for (Int_t i = 0; i < n; ++i)
512 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
513
514
515 gluEndPolygon(t);
516}
517
518////////////////////////////////////////////////////////////////////////////////
519///Draw poly-line in user coordinates.
520
521template<class ValueType>
522void TGLPadPainter::DrawPolyLineHelper(Int_t n, const ValueType *x, const ValueType *y)
523{
524 if (fLocked) {
525 if (IsInvertMode() && (n > 1)) {
526 std::vector<TPoint> xy(n);
527 for (Int_t i = 0; i < n; ++i) {
528 xy[i].fX = (SCoord_t) gPad->XtoAbsPixel(x[i]);
529 xy[i].fY = (SCoord_t) gPad->YtoAbsPixel(y[i]);
530 }
531 gVirtualX->DrawPolyLineW(fWinContext, xy.size(), xy.data());
532 }
533 return;
534 }
535
537
538 glBegin(GL_LINE_STRIP);
539
540 for (Int_t i = 0; i < n; ++i)
541 glVertex2d(x[i], y[i]);
542
543 if (fIsHollowArea) {
544 glVertex2d(x[0], y[0]);
546 }
547 glEnd();
548
550 Double_t pointSize = GetAttLine().GetLineWidth();
556 glBegin(GL_POINTS);
557
558 for (Int_t i = 0; i < n; ++i)
559 glVertex2d(x[i], y[i]);
560
561 glEnd();
562 glPointSize(1.f);
563 }
564}
565
566////////////////////////////////////////////////////////////////////////////////
567/// Draw poly-line in user coordinates.
568
570{
572}
573
574////////////////////////////////////////////////////////////////////////////////
575/// Draw poly-line in user coordinates.
576
578{
580}
581
582////////////////////////////////////////////////////////////////////////////////
583///Poly line in NDC.
584
586{
587 if (fLocked) return;
588
590 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
591 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
592 const Double_t x1 = gPad->GetX1(), y1 = gPad->GetY1();
593
594 glBegin(GL_LINE_STRIP);
595
596 for (Int_t i = 0; i < n; ++i)
597 glVertex2d(x1 + u[i] * xRange, y1 + v[i] * yRange);
598
599 glEnd();
600}
601
602////////////////////////////////////////////////////////////////////////////////
603/// Returns true when invert mode is configured and painter in locked state
604/// Used when non-opaque of objects moving is involved
605
610
611////////////////////////////////////////////////////////////////////////////////
612///Poly-marker drawing
613
614template<class ValueType>
615void TGLPadPainter::DrawPolyMarkerHelper(Int_t n, const ValueType *x, const ValueType *y)
616{
617 std::vector<TPoint> poly(n);
618
619 if (fLocked) {
620 if (IsInvertMode()) {
621 for (Int_t i = 0; i < n; ++i) {
622 poly[i].fX = gPad->XtoAbsPixel(x[i]);
623 poly[i].fY = gPad->YtoAbsPixel(y[i]);
624 }
625 gVirtualX->DrawPolyMarkerW(fWinContext, poly.size(), poly.data());
626 }
627 return;
628 }
629
630 const UInt_t padH = gPad->GetPadHeight();
631
632 for (Int_t i = 0; i < n; ++i) {
633 poly[i].fX = gPad->XtoPixel(x[i]);
634 poly[i].fY = padH - gPad->YtoPixel(y[i]);
635 }
636
639 //
640 glOrtho(0, gPad->GetPadWidth(), 0, gPad->GetPadHeight(), -10., 10.);
641 //
643 //
645
646 Float_t rgba[4] = {};
650
653
654 fMarker.SetMarkerSizeWidth(GetAttMarker().GetMarkerSize(), w);
655
657 switch (markerStyle) {
658 case kDot:
659 fMarker.DrawDot(n, poly.data());
660 break;
661 case kPlus:
662 fMarker.DrawPlus(n, poly.data());
663 break;
664 case kStar:
665 case 31:
666 fMarker.DrawStar(n, poly.data());
667 break;
668 case kCircle:
669 case kOpenCircle:
670 fMarker.DrawCircle(n, poly.data());
671 break;
672 case kMultiply:
673 fMarker.DrawX(n, poly.data());
674 break;
675 case kFullDotSmall://"Full dot small"
677 break;
678 case kFullDotMedium:
680 break;
681 case kFullDotLarge:
682 case kFullCircle:
684 break;
685 case kFullSquare:
686 fMarker.DrawFullSquare(n, poly.data());
687 break;
688 case kFullTriangleUp:
690 break;
693 break;
694 case kOpenSquare:
696 fMarker.DrawFullSquare(n, poly.data());
698 break;
699 case kOpenTriangleUp:
703 break;
704 case kOpenDiamond:
705 fMarker.DrawDiamond(n, poly.data());
706 break;
707 case kOpenCross:
708 fMarker.DrawOpenCross(n, poly.data());
709 break;
710 case kFullStar:
711 fMarker.DrawFullStar(n, poly.data());
712 break;
713 case kOpenStar:
714 fMarker.DrawOpenStar(n, poly.data());
715 break;
718 break;
719 case kFullDiamond:
720 fMarker.DrawFullDiamond(n, poly.data());
721 break;
722 case kFullCross:
723 fMarker.DrawFullCross(n, poly.data());
724 break;
727 break;
730 break;
733 break;
734 case kOctagonCross:
736 break;
739 break;
742 break;
745 break;
748 break;
751 break;
754 break;
757 break;
758 case kOpenCrossX:
759 fMarker.DrawOpenCrossX(n, poly.data());
760 break;
761 case kFullCrossX:
762 fMarker.DrawFullCrossX(n, poly.data());
763 break;
764 case kFourSquaresX:
766 break;
767 case kFourSquaresPlus:
769 break;
770 }
771
774 glLineWidth(1.f);
775}
776
777////////////////////////////////////////////////////////////////////////////////
778///Poly-marker.
779
784
785////////////////////////////////////////////////////////////////////////////////
786///Poly-marker.
787
792
793////////////////////////////////////////////////////////////////////////////////
794/// Select specified font/size
795
797{
798 //10 is the first valid font index.
799 //20 is FreeSerifBold, as in TTF.cxx and in TGLFontManager.cxx.
800 //shift - is the shift to access "extended" fonts.
802
803 Int_t fontIndex = TMath::Max(Font_t(10), font);
804 if (fontIndex / 10 + shift > TGLFontManager::GetFontFileArray()->GetEntries())
805 fontIndex = 20 + shift * 10;
806 else
807 fontIndex += shift * 10;
808
809 Int_t textSize = TMath::Max(Int_t(tsize) - 1, 10);
810
812
814}
815
816////////////////////////////////////////////////////////////////////////////////
817/// Helper function to draw text
818
819template<class Char>
821{
823
825 //
826 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
827 //
829
830 Float_t rgba[4] = {};
833
834 SelectGLFont(GetAttText().GetTextFont(), GetAttText().GetTextSizePixels(*gPad));
835
837
838 fF.PreRender();
839
840 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
841 fF.Render(text, gPad->XtoPixel(x), padH - gPad->YtoPixel(y), GetTextAngle(), GetTextMagnitude());
842
843 fF.PostRender();
845
847}
848
849////////////////////////////////////////////////////////////////////////////////
850/// Helper function to get text extent
851
852template<class Char_t>
854{
855 SelectGLFont(font, size);
856
857 Float_t llx, lly, llz, urx, ury, urz;
858 fF.BBox(text, llx, lly, llz, urx, ury, urz);
859 urx -= llx;
860 ury -= lly;
861 w = (UInt_t) (urx > 0. ? urx : 0.);
862 h = (UInt_t) (ury > 0. ? ury : 0.);
863 (void) llz;
864 (void) urz;
865}
866
867////////////////////////////////////////////////////////////////////////////////
868/// Helper function to get text ascent / descent
869
870template<class Char_t>
872{
873 SelectGLFont(font, size);
874
875 Float_t llx, lly, llz, urx, ury, urz;
876 fF.BBox(text, llx, lly, llz, urx, ury, urz);
877 a = (UInt_t) (ury > 0. ? ury : 0.);
878 d = (UInt_t) (lly < 0. ? -lly : 0.);
879 (void) llx;
880 (void) llz;
881 (void) urx;
882 (void) urz;
883}
884
885////////////////////////////////////////////////////////////////////////////////
886///Draw text. This operation is especially
887///dangerous if in locked state -
888///ftgl will assert on zero texture size
889///(which is result of bad GL context).
890
892{
893 if (fLocked) return;
894
895 if (GetAttText().GetTextSize() > 0)
897}
898
899////////////////////////////////////////////////////////////////////////////////
900///Draw text. This operation is especially
901///dangerous if in locked state -
902///ftgl will assert on zero texture size
903///(which is result of bad GL context).
904
906{
907 if (fLocked) return;
908
909 if (GetAttText().GetTextSize() > 0)
911}
912
913////////////////////////////////////////////////////////////////////////////////
914///Draw text in NDC. This operation is especially
915///dangerous if in locked state -
916///ftgl will assert on zero texture size
917///(which is result of bad GL context).
918
920{
921 if (fLocked) return;
922
923 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
924 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
925 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
926}
927
928////////////////////////////////////////////////////////////////////////////////
929/// Get text extent
930
932{
933 TextExtentHelper(font, size, w, h, text);
934}
935
936////////////////////////////////////////////////////////////////////////////////
937/// Get text extent
938
940{
941 TextExtentHelper(font, size, w, h, text);
942}
943
944////////////////////////////////////////////////////////////////////////////////
945/// Get text extent
946
951
952////////////////////////////////////////////////////////////////////////////////
953/// Get text extent
954
959
960////////////////////////////////////////////////////////////////////////////////
961/// Get text advance
962
964{
965 SelectGLFont(font, size);
966
967 auto advance = fF.Advance(text);
968
969 return (UInt_t) (advance > 0. ? advance : 0.);
970}
971
972////////////////////////////////////////////////////////////////////////////////
973///Draw text in NDC. This operation is especially
974///dangerous if in locked state -
975///ftgl will assert on zero texture size
976///(which is result of bad GL context).
977
979{
980 if (fLocked) return;
981
982 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
983 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
984 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
985}
986
987////////////////////////////////////////////////////////////////////////////////
988///Save the projection matrix.
989///Attention! GL_PROJECTION will become the current matrix
990///after this call!
991
997
998////////////////////////////////////////////////////////////////////////////////
999///Restore the projection matrix.
1000///Attention! GL_PROJECTION will become the current matrix
1001///after this call!
1002
1008
1009////////////////////////////////////////////////////////////////////////////////
1010///Save the modelview matrix.
1011///Attention! GL_MODELVIEW will become the current matrix
1012///after this call!
1013
1019
1020////////////////////////////////////////////////////////////////////////////////
1021///Restore the modelview matrix.
1022///Attention! GL_MODELVIEW will become the current matrix
1023///after this call!
1024
1030
1031////////////////////////////////////////////////////////////////////////////////
1032///Extract and save the current viewport.
1033
1038
1039////////////////////////////////////////////////////////////////////////////////
1040///Restore the saved viewport.
1041
1043{
1044 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
1045}
1046
1047////////////////////////////////////////////////////////////////////////////////
1048/// Using TImage save frame-buffer contents as a picture.
1049
1050void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
1051{
1052 auto canvas = pad->GetCanvas();
1053 if (!canvas)
1054 return;
1055
1056 canvas->Flush();
1057
1058 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
1061 //In case GL_BGRA is not in gl.h (old windows' gl) - comment/uncomment lines.
1062 //glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_BGRA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
1063 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
1064
1065 std::unique_ptr<TImage> image(TImage::Create());
1066 if (!image.get()) {
1067 ::Error("TGLPadPainter::SaveImage", "TImage creation failed");
1068 return;
1069 }
1070
1071 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
1072 UInt_t *argb = image->GetArgbArray();
1073
1074 if (!argb) {
1075 ::Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
1076 return;
1077 }
1078
1079 const Int_t nLines = canvas->GetWh();
1080 const Int_t nPixels = canvas->GetWw();
1081
1082 for (Int_t i = 0; i < nLines; ++i) {
1083 Int_t base = (nLines - 1 - i) * nPixels;
1084 for (Int_t j = 0; j < nPixels; ++j, ++base) {
1085 //Uncomment/comment if you don't have GL_BGRA.
1086
1087 const UInt_t pix = buff[base];
1088 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
1089 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
1090
1091 //argb[i * nPixels + j] = buff[base];
1092 argb[i * nPixels + j] = bgra;
1093 }
1094 }
1095
1096 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
1097}
1098
1099////////////////////////////////////////////////////////////////////////////////
1100
1103{
1104 if (fLocked)
1105 return;
1106
1107 if (!pixelData) {
1108 //I'd prefer an assert.
1109 ::Error("TGLPadPainter::DrawPixels", "pixel data is null");
1110 return;
1111 }
1112
1113 if (std::numeric_limits<UInt_t>::digits >= 32) {
1114 //TASImage uses bit 31 as ...
1115 //alpha channel flag! FUUUUUUUUUUUUU ..... !!!
1116 CLRBIT(width, 31);
1117 CLRBIT(height, 31);
1118 }
1119
1120 if (!width) {
1121 //Assert is better.
1122 ::Error("TGLPadPainter::DrawPixels", "invalid width");
1123 return;
1124 }
1125
1126 if (!height) {
1127 //Assert is better.
1128 ::Error("TGLPadPainter::DrawPixels", "invalid height");
1129 return;
1130 }
1131
1132 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
1133 //TASImage passes pixel coordinates in pad's pixmap coordinate space.
1134 //While glRasterPosX said to work with 'window' coordinates,
1135 //that's a lie :) it does not :)
1136
1137 const Double_t rasterX = Double_t(dstX) / (pad->GetAbsWNDC() * pad->GetWw()) *
1138 (pad->GetX2() - pad->GetX1()) + pad->GetX1();
1139
1140 const Double_t yRange = pad->GetY2() - pad->GetY1();
1141 const Double_t rasterY = yRange - Double_t(dstY + height) / (pad->GetAbsHNDC() * pad->GetWh()) * yRange +
1142 pad->GetY1();
1143
1144 GLdouble oldPos[4] = {};
1145 //Save the previous raster pos.
1147
1149 //Stupid asimage provides us upside-down image.
1150 std::vector<unsigned char> upsideDownImage(4 * width * height);
1151 const unsigned char *srcLine = pixelData + 4 * width * (height - 1);
1152 unsigned char *dstLine = &upsideDownImage[0];
1153 for (UInt_t i = 0; i < height; ++i, srcLine -= 4 * width, dstLine += 4 * width)
1154 std::copy(srcLine, srcLine + 4 * width, dstLine);
1155
1156 if (enableBlending) {
1159 }
1160
1162
1163 if (enableBlending)
1165
1166 //Restore raster pos.
1167 glRasterPos2d(oldPos[0], oldPos[1]);
1168 } else
1169 ::Error("TGLPadPainter::DrawPixels", "no pad found to draw");
1170}
1171
1172//Aux. functions - gradient and solid fill of arbitrary area.
1173
1174////////////////////////////////////////////////////////////////////////////////
1175///At the moment I assume both linear and radial gradients will work the same way -
1176///using a stencil buffer and some big rectangle(s) to fill with a gradient.
1177///Thus I have a 'common' part - the part responsible for a stencil test.
1178
1180{
1181 assert(n > 2 && "DrawPolygonWithGradient, invalid number of points");
1182 assert(x != nullptr && "DrawPolygonWithGradient, parameter 'x' is null");
1183 assert(y != nullptr && "DrawPolygonWithGradient, parameter 'y' is null");
1184
1185 auto grad = dynamic_cast<TColorGradient *>(gROOT->GetColor(fGlFillAtt.GetFillColor()));
1186 assert(grad != nullptr && "DrawPolygonWithGradient, the current fill color is not a gradient fill");
1187
1188 if (fLocked)
1189 return;
1190
1191 //Now, some magic!
1193
1194 //TODO: check that the state is restored back correctly after
1195 // we done with a gradient.
1196 //TODO: make sure that we have glDepthMask set to false in general!
1198
1199 glStencilFunc(GL_NEVER, 1, 0xFF);
1200 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);// draw 1s on test fail (always)
1201 //Draw stencil pattern
1202 glStencilMask(0xFF);
1204
1205 //Draw our polygon into the stencil buffer:
1206 DrawTesselation(n, x, y);
1207
1209 glStencilMask(0x00);
1210 //Draw where stencil's value is 0
1211 glStencilFunc(GL_EQUAL, 0, 0xFF);
1212 //Draw only where stencil's value is 1
1213 glStencilFunc(GL_EQUAL, 1, 0xFF);
1214
1215 //At the moment radial gradient is derived from linear - it was convenient
1216 //at some point, but in fact it was a bad idea. And now I have to
1217 //first check radial gradient.
1218 //TODO: TRadialGradient must inherit TColorGradient directly.
1219 const TRadialGradient * const rGrad = dynamic_cast<const TRadialGradient *>(grad);
1220 if (rGrad)
1221 DrawGradient(rGrad, n, x, y);
1222 else {
1223 const TLinearGradient * const lGrad = dynamic_cast<const TLinearGradient *>(grad);
1224 assert(lGrad != nullptr && "DrawPolygonWithGradient, unknown gradient type");
1225 DrawGradient(lGrad, n, x, y);
1226 }
1227}
1228
1229////////////////////////////////////////////////////////////////////////////////
1230
1232 const Double_t *xs, const Double_t *ys)
1233{
1234 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1235 assert(nPoints > 2 && "DrawGradient, invalid number of points");
1236 assert(xs != nullptr && "DrawGradient, parameter 'xs' is null");
1237 assert(ys != nullptr && "DrawGradient, parameter 'ys' is null");
1238
1240 ::Warning("TGLPadPainter::DrawGradient",
1241 "extended radial gradient is not supported");//yet?
1242 return;
1243 }
1244
1245 //TODO: check the polygon's bbox!
1246 const auto &bbox = Rgl::Pad::FindBoundingRect(nPoints, xs, ys);
1247 //
1248 auto center = grad->GetCenter();
1249 auto radius = grad->GetRadius();
1250 //Adjust the center and radius depending on coordinate mode.
1252 radius *= TMath::Max(bbox.fWidth, bbox.fHeight);
1253 center.fX = bbox.fWidth * center.fX + bbox.fXMin;
1254 center.fY = bbox.fHeight * center.fY + bbox.fYMin;
1255 } else {
1256 const auto w = gPad->GetX2() - gPad->GetX1();
1257 const auto h = gPad->GetY2() - gPad->GetY1();
1258
1259 radius *= TMath::Max(w, h);
1260 center.fX *= w;
1261 center.fY *= h;
1262 }
1263 //Now for the gradient fill we switch into pixel coordinates:
1264 const auto pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1265 const auto pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1266 //
1269 //A new ortho projection:
1272 //
1273 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1274 //
1276 center.fX = gPad->XtoPixel(center.fX);
1277 center.fY = pixelH - gPad->YtoPixel(center.fY);
1278
1279 Double_t maxR = 0.;
1280 {
1281 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1282 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1283 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1284 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1285 //Get the longest distance from the center to the bounding box vertices
1286 //(this will be the maximum possible radius):
1287 const Double_t maxDistX = TMath::Max(TMath::Abs(center.fX - xMin),
1288 TMath::Abs(center.fX - xMax));
1289 const Double_t maxDistY = TMath::Max(TMath::Abs(center.fY - yMin),
1290 TMath::Abs(center.fY - yMax));
1292 }
1293
1294 //If gradient 'stops inside the polygon', we use
1295 //the solid fill for the area outside of radial gradient:
1296 const Bool_t solidFillAfter = maxR > radius;
1297 //We emulate a radial gradient using triangles and linear gradient:
1298 //TODO: Can be something smarter? (btw even 100 seems to be enough)
1299 const UInt_t nSlices = 500;
1300
1301 const auto nColors = grad->GetNumberOfSteps();
1302 //+1 - the strip from the last color's position to radius,
1303 //and (probably) + 1 for solidFillAfter.
1304 const auto nCircles = nColors + 1 + solidFillAfter;
1305
1306 //TODO: can locations be outside of [0., 1.] ???
1307 //at the moment I assume the answer is NO, NEVER.
1308 const auto locations = grad->GetColorPositions();
1309 // * 2 below == x,y
1310 std::vector<Double_t> circles(nSlices * nCircles * 2);
1311 const Double_t angle = TMath::TwoPi() / nSlices;
1312
1313 //"Main" circles (for colors at locations[i]).
1314 for (UInt_t i = 0; i < nColors; ++i) {
1315 const auto circle = &circles[i * nSlices * 2];
1316 //TODO: either check locations here or somewhere else.
1317 const auto r = radius * locations[i];
1318 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1319 circle[j] = center.fX + r * TMath::Cos(angle * j);
1320 circle[j + 1] = center.fY + r * TMath::Sin(angle * j);
1321 }
1322 //The "closing" vertices:
1323 circle[(nSlices - 1) * 2] = circle[0];
1324 circle[(nSlices - 1) * 2 + 1] = circle[1];
1325 }
1326
1327 {
1328 //The strip between lastPos and radius:
1329 const auto circle = &circles[nColors * nSlices * 2];
1330 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1331 circle[j] = center.fX + radius * TMath::Cos(angle * j);
1332 circle[j + 1] = center.fY + radius * TMath::Sin(angle * j);
1333 }
1334
1335 circle[(nSlices - 1) * 2] = circle[0];
1336 circle[(nSlices - 1) * 2 + 1] = circle[1];
1337 }
1338
1339 if (solidFillAfter) {
1340 //The strip after the radius:
1341 const auto circle = &circles[(nCircles - 1) * nSlices * 2];
1342 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1343 circle[j] = center.fX + maxR * TMath::Cos(angle * j);
1344 circle[j + 1] = center.fY + maxR * TMath::Sin(angle * j);
1345 }
1346
1347 circle[(nSlices - 1) * 2] = circle[0];
1348 circle[(nSlices - 1) * 2 + 1] = circle[1];
1349 }
1350
1351 //Now we draw:
1352 //1) triangle fan in the center (from center to the locations[1],
1353 // with a solid fill).
1354 //2) quad strips for colors.
1355 //3) additional quad strip from the lastLocation to the radius
1356 //4) additional quad strip (if any) from the radius to maxR.
1357
1358 //RGBA values:
1359 const auto rgba = grad->GetColors();
1360
1362 //TODO?
1364
1365 //Probably a degenerated case. Maybe not.
1368 glVertex2d(center.fX, center.fY);
1369
1370 for (UInt_t i = 0, e = nSlices * 2; i < e; i += 2)
1371 glVertex2dv(&circles[i]);
1372
1373 glEnd();
1374
1375 //No auto for circles, explicit types to have const Double_t * const, not Duble_t * const.
1376 for (UInt_t i = 0; i < nColors - 1; ++i) {
1377 const Double_t * const inner = &circles[i * nSlices * 2];
1378 const auto innerRGBA = rgba + i * 4;
1379 const auto outerRGBA = rgba + (i + 1) * 4;
1380 const Double_t * const outer = &circles[(i + 1) * nSlices * 2];
1381
1383 }
1384
1385 //Probably degenerated strip.
1386 {
1387 const Double_t * const inner = &circles[nSlices * (nColors - 1) * 2];
1388 const auto solidRGBA = rgba + (nColors - 1) * 4;
1389 const Double_t * const outer = &circles[nSlices * nColors * 2];
1390
1392 }
1393
1394 if (solidFillAfter) {
1395 const Double_t * const inner = &circles[nSlices * nColors * 2];
1396 const auto solidRGBA = rgba + (nColors - 1) * 4;
1397 const Double_t * const outer = &circles[nSlices * (nColors + 1) * 2];
1398
1400 }
1401
1404}
1405
1406////////////////////////////////////////////////////////////////////////////////
1407
1409 const Double_t *x, const Double_t *y)
1410{
1411 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1412 assert(n > 2 && "DrawGradient, invalid number of points");
1413 assert(x != nullptr && "DrawGradient, parameter 'x' is null");
1414 assert(y != nullptr && "DrawGradient, parameter 'y' is null");
1415
1416 //Now we fill the whole scene with one big rectangle
1417 //(group of rectangles) with a gradient fill using
1418 //stencil test.
1419
1420 //Find a bounding rect.
1421 const auto &bbox = Rgl::Pad::FindBoundingRect(n, x, y);
1422 //TODO: check the bbox??
1423
1424 //For the gradient fill we switch into the
1425 //pixel coordinates.
1428
1429 //A new ortho projection:
1432
1433 const Double_t pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1434 const Double_t pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1435 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1436
1437 //A new modelview:
1440 //
1441 TColorGradient::Point start = grad->GetStart();
1442 TColorGradient::Point end = grad->GetEnd();
1443
1444 //Change gradient coordinates from 'NDC' to pad coords:
1446 {
1447 const Double_t w = gPad->GetX2() - gPad->GetX1();
1448 const Double_t h = gPad->GetY2() - gPad->GetY1();
1449
1450 start.fX = start.fX * w;
1451 start.fY = start.fY * h;
1452 end.fX = end.fX * w;
1453 end.fY = end.fY * h;
1454 } else {
1455 start.fX = start.fX * bbox.fWidth + bbox.fXMin;
1456 start.fY = start.fY * bbox.fHeight + bbox.fYMin;
1457 end.fX = end.fX * bbox.fWidth + bbox.fXMin;
1458 end.fY = end.fY * bbox.fHeight + bbox.fYMin;
1459 }
1460
1461 //TODO: with a radial fill we'll have to extract the code
1462 // below into the separate function/and have additional function
1463 // for a radial gradient.
1464 //Now from pad to pixels:
1465 start.fX = gPad->XtoPixel(start.fX);
1466 start.fY = pixelH - gPad->YtoPixel(start.fY);
1467 end.fX = gPad->XtoPixel(end.fX);
1468 end.fY = pixelH - gPad->YtoPixel(end.fY);
1469 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1470 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1471 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1472 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1473 //
1474
1475 //TODO: check all calculations!
1476
1477 //Get the longest distance from the start point to the bounding box vertices:
1478 const Double_t maxDistX = TMath::Max(TMath::Abs(start.fX - xMin), TMath::Abs(start.fX - xMax));
1479 const Double_t maxDistY = TMath::Max(TMath::Abs(start.fY - yMin), TMath::Abs(start.fY - yMax));
1480
1481 const Double_t startEndLength = TMath::Sqrt((end.fX - start.fX) * (end.fX - start.fX) +
1482 (end.fY - start.fY) * (end.fY - start.fY));
1485
1486 //Boxes with a gradients to emulate gradient fill with many colors:
1487 const Double_t * const colorPositions = grad->GetColorPositions();
1488 std::vector<Double_t> gradBoxes(grad->GetNumberOfSteps() + 2);
1489 gradBoxes[0] = start.fY - h;
1490 for (unsigned i = 1; i <= grad->GetNumberOfSteps(); ++i)
1491 gradBoxes[i] = startEndLength * colorPositions[i - 1] + start.fY;
1492
1493 gradBoxes[grad->GetNumberOfSteps() + 1] = start.fY + h;
1494
1495 //Rotation angle - gradient's axis:
1496 Double_t angle = TMath::ACos((startEndLength * (end.fY - start.fY)) /
1498 if (end.fX > start.fX)
1499 angle *= -1;
1500
1501 glTranslated(start.fX, start.fY, 0.);
1502 glRotated(angle, 0., 0., 1.);
1503 glTranslated(-start.fX, -start.fY, 0.);
1504 //
1505 const Double_t * const rgba = grad->GetColors();
1506
1507 const unsigned nEdges = gradBoxes.size();
1508 const unsigned nColors = grad->GetNumberOfSteps();
1509 const Double_t xLeft = start.fX - h, xRight = start.fX + h;
1510
1512 //TODO?
1514
1517 rgba + (nColors - 1) * 4, rgba + (nColors - 1) * 4);
1518
1519 for (unsigned i = 1; i < nEdges - 2; ++i)
1521 xRight, rgba + (i - 1) * 4, rgba + i * 4);
1522
1525}
1526
1527////////////////////////////////////////////////////////////////////////////////
1528
1530{
1531 assert(n > 2 && "DrawTesselation, invalid number of points");
1532 assert(x != nullptr && "DrawTesselation, parameter 'x' is null");
1533 assert(y != nullptr && "DrawTesselation, parameter 'y' is null");
1534
1535 //Data for a tesselator:
1536 fVs.resize(n * 3);
1537
1538 for (Int_t i = 0; i < n; ++i) {
1539 fVs[i * 3] = x[i];
1540 fVs[i * 3 + 1] = y[i];
1541 fVs[i * 3 + 2] = 0.;
1542 }
1543
1544 //TODO: A very primitive way to tesselate - check what
1545 //kind of polygons we can really have from TPad/TCanvas.
1547 gluBeginPolygon(t);
1549
1550 for (Int_t i = 0; i < n; ++i)
1551 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
1552
1553 gluEndPolygon(t);
1554}
1555
#define d(i)
Definition RSha256.hxx:102
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
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
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
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
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
short SCoord_t
Screen coordinates (short)
Definition RtypesCore.h:100
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
char name[80]
Definition TGX11.cxx:148
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:777
#define gROOT
Definition TROOT.h:417
#define gPad
#define gVirtualX
Definition TVirtualX.h:377
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 SetMarkerSizeWidth(Size_t size, Width_t width)
Set marker size and line width.
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
Fill Area Attributes class.
Definition TAttFill.h:21
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:32
Line Attributes class.
Definition TAttLine.h:21
Marker Attributes class.
Definition TAttMarker.h:21
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.
Float_t Advance(const char *txt) const
Get advance.
void SetTextAlign(UInt_t align)
void BBox(const char *txt, Float_t &llx, Float_t &lly, Float_t &llz, Float_t &urx, Float_t &ury, Float_t &urz) const
Get bounding box.
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 DrawPolyMarkerHelper(Int_t n, const ValueType *x, const ValueType *y)
Poly-marker drawing.
void TextExtentHelper(Font_t font, Double_t size, UInt_t &w, UInt_t &h, const Char_t *text)
Helper function to get text extent.
void SetDrawMode(Int_t device, Int_t mode) override
Set drawing mode for specified device.
void TextAscentDescentHelper(Font_t font, Double_t size, UInt_t &a, UInt_t &d, const Char_t *text)
Helper function to get text ascent / descent.
void DrawPixels(const unsigned char *pixelData, UInt_t width, UInt_t height, Int_t dstX, Int_t dstY, Bool_t enableBlending) override
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
void SelectGLFont(Font_t font, Float_t size)
Select specified font/size.
void DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2) override
Draw line segment in NDC coordinates.
WinContext_t fWinContext
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 SetAttLine(const TAttLine &att) override
Set line attributes.
TAttFill fGlFillAtt
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...
Bool_t IsInvertMode()
Returns true when invert mode is configured and painter in locked state Used when non-opaque of objec...
void GetTextAscentDescent(Font_t font, Double_t size, UInt_t &a, UInt_t &d, const char *mess) override
Get text extent.
void InvalidateCS() override
When TPad::Range for gPad is called, projection must be changed in OpenGL.
void ClearDrawable() override
Do nothing, sub-pads not cleared in GL.
void ClearWindow(Int_t device) override
Clear specified window - calling gVirtualX->ClearWindowW.
void DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v) override
Poly line in NDC.
void OnPad(TVirtualPad *) override
Select pad where current painting will be performed.
void DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y) override
Draw poly-line in user coordinates.
Rgl::Pad::GLLimits fLimits
void SetOpacity(Int_t percent) override
Delegate to gVirtualX.
void DrawTextNDC(Double_t x, Double_t y, const char *text, ETextMode mode) override
Draw text in NDC.
void SetAttFill(const TAttFill &att) override
Set fill attributes.
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 SaveViewport()
Extract and save the current viewport.
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 DrawFillArea(Int_t n, const Double_t *x, const Double_t *y) override
Draw tesselated polygon (probably, outline only).
void DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y) override
Poly-marker.
void DrawPolyLineHelper(Int_t n, const ValueType *x, const ValueType *y)
Draw poly-line in user coordinates.
void UpdateDrawable(Int_t mode) override
Call low-level update of selected drawable, redirect to gVirtualX.
void RestoreProjectionMatrix() const
Restore the projection matrix.
void SetAttMarker(const TAttMarker &att) override
Set marker attributes.
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.
void DrawTesselation(Int_t n, const Double_t *x, const Double_t *y)
Int_t CreateDrawable(UInt_t w, UInt_t h) override
Not required at the moment.
UInt_t GetTextAdvance(Font_t font, Double_t size, const char *text, Bool_t kern) override
Get text advance.
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 GetTextExtent(Font_t font, Double_t size, UInt_t &w, UInt_t &h, const char *mess) override
Get text extent.
Bool_t IsCocoa() const override
Returns true when cocoa backend is used.
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.
void SetAttFill(const TAttFill &att) override
Set fill attributes.
Color_t GetMarkerColor() const override
const TAttText & GetAttText() const override
Get text attributes.
Short_t GetTextAlign() const override
const TAttMarker & GetAttMarker() const override
Get marker attributes.
Style_t GetMarkerStyle() const override
Font_t GetTextFont() const override
Width_t GetLineWidth() const override
Bool_t fFullyTransparent
if transformed fill attributes fully transparent
void SetAttMarker(const TAttMarker &att) override
Set marker attributes.
void SetAttLine(const TAttLine &att) override
Set line attributes.
Float_t GetTextAngle() const override
TAttFill GetAttFillInternal(Bool_t with_transparency)
Returns fill attributes after modification Checks for special fill styles 4000 .
Color_t GetTextColor() const override
Style_t GetLineStyle() const override
const TAttLine & GetAttLine() const override
Get line attributes.
Float_t GetTextSize() const override
The most important graphics class in the ROOT system.
Definition TPad.h:28
SCoord_t fY
Definition TPoint.h:36
SCoord_t fX
Definition TPoint.h:35
Double_t GetRadius() const
Get radius.
const Point & GetCenter() const
Get center.
EGradientType GetGradientType() const
Get gradient type.
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
BoundingRect< ValueType > FindBoundingRect(Int_t nPoints, const ValueType *xs, const ValueType *ys)
void ExtractRGBA(Color_t colorIndex, Float_t *rgba)
void DrawQuadStripWithRadialGradientFill(unsigned nPoints, const Double_t *inner, const Double_t *innerRGBA, const Double_t *outer, const Double_t *outerRGBA)
TODO: is it possible to use GLdouble to avoid problems with Double_t/GLdouble if they are not the sam...
Definition TGLUtil.cxx:3216
void DrawBoxWithGradientFill(Double_t y1, Double_t y2, Double_t x1, Double_t x2, const Double_t *rgba1, const Double_t *rgba2)
Definition TGLUtil.cxx:3196
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Definition TMath.h:643
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:605
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:599
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition TMath.h:75
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
constexpr Double_t TwoPi()
Definition TMath.h:47