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///Draw text. This operation is especially
851///dangerous if in locked state -
852///ftgl will assert on zero texture size
853///(which is result of bad GL context).
854
856{
857 if (fLocked) return;
858
859 if (GetAttText().GetTextSize() > 0)
861}
862
863////////////////////////////////////////////////////////////////////////////////
864///Draw text. This operation is especially
865///dangerous if in locked state -
866///ftgl will assert on zero texture size
867///(which is result of bad GL context).
868
870{
871 if (fLocked) return;
872
873 if (GetAttText().GetTextSize() > 0)
875}
876
877////////////////////////////////////////////////////////////////////////////////
878///Draw text in NDC. This operation is especially
879///dangerous if in locked state -
880///ftgl will assert on zero texture size
881///(which is result of bad GL context).
882
884{
885 if (fLocked) return;
886
887 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
888 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
889 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
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///Save the projection matrix.
909///Attention! GL_PROJECTION will become the current matrix
910///after this call!
911
917
918////////////////////////////////////////////////////////////////////////////////
919///Restore the projection matrix.
920///Attention! GL_PROJECTION will become the current matrix
921///after this call!
922
928
929////////////////////////////////////////////////////////////////////////////////
930///Save the modelview matrix.
931///Attention! GL_MODELVIEW will become the current matrix
932///after this call!
933
939
940////////////////////////////////////////////////////////////////////////////////
941///Restore the modelview matrix.
942///Attention! GL_MODELVIEW will become the current matrix
943///after this call!
944
950
951////////////////////////////////////////////////////////////////////////////////
952///Extract and save the current viewport.
953
958
959////////////////////////////////////////////////////////////////////////////////
960///Restore the saved viewport.
961
963{
964 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
965}
966
967////////////////////////////////////////////////////////////////////////////////
968/// Using TImage save frame-buffer contents as a picture.
969
970void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
971{
972 auto canvas = pad->GetCanvas();
973 if (!canvas)
974 return;
975
976 canvas->Flush();
977
978 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
981 //In case GL_BGRA is not in gl.h (old windows' gl) - comment/uncomment lines.
982 //glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_BGRA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
983 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
984
985 std::unique_ptr<TImage> image(TImage::Create());
986 if (!image.get()) {
987 ::Error("TGLPadPainter::SaveImage", "TImage creation failed");
988 return;
989 }
990
991 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
992 UInt_t *argb = image->GetArgbArray();
993
994 if (!argb) {
995 ::Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
996 return;
997 }
998
999 const Int_t nLines = canvas->GetWh();
1000 const Int_t nPixels = canvas->GetWw();
1001
1002 for (Int_t i = 0; i < nLines; ++i) {
1003 Int_t base = (nLines - 1 - i) * nPixels;
1004 for (Int_t j = 0; j < nPixels; ++j, ++base) {
1005 //Uncomment/comment if you don't have GL_BGRA.
1006
1007 const UInt_t pix = buff[base];
1008 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
1009 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
1010
1011 //argb[i * nPixels + j] = buff[base];
1012 argb[i * nPixels + j] = bgra;
1013 }
1014 }
1015
1016 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
1017}
1018
1019////////////////////////////////////////////////////////////////////////////////
1020
1023{
1024 if (fLocked)
1025 return;
1026
1027 if (!pixelData) {
1028 //I'd prefer an assert.
1029 ::Error("TGLPadPainter::DrawPixels", "pixel data is null");
1030 return;
1031 }
1032
1033 if (std::numeric_limits<UInt_t>::digits >= 32) {
1034 //TASImage uses bit 31 as ...
1035 //alpha channel flag! FUUUUUUUUUUUUU ..... !!!
1036 CLRBIT(width, 31);
1037 CLRBIT(height, 31);
1038 }
1039
1040 if (!width) {
1041 //Assert is better.
1042 ::Error("TGLPadPainter::DrawPixels", "invalid width");
1043 return;
1044 }
1045
1046 if (!height) {
1047 //Assert is better.
1048 ::Error("TGLPadPainter::DrawPixels", "invalid height");
1049 return;
1050 }
1051
1052 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
1053 //TASImage passes pixel coordinates in pad's pixmap coordinate space.
1054 //While glRasterPosX said to work with 'window' coordinates,
1055 //that's a lie :) it does not :)
1056
1057 const Double_t rasterX = Double_t(dstX) / (pad->GetAbsWNDC() * pad->GetWw()) *
1058 (pad->GetX2() - pad->GetX1()) + pad->GetX1();
1059
1060 const Double_t yRange = pad->GetY2() - pad->GetY1();
1061 const Double_t rasterY = yRange - Double_t(dstY + height) / (pad->GetAbsHNDC() * pad->GetWh()) * yRange +
1062 pad->GetY1();
1063
1064 GLdouble oldPos[4] = {};
1065 //Save the previous raster pos.
1067
1069 //Stupid asimage provides us upside-down image.
1070 std::vector<unsigned char> upsideDownImage(4 * width * height);
1071 const unsigned char *srcLine = pixelData + 4 * width * (height - 1);
1072 unsigned char *dstLine = &upsideDownImage[0];
1073 for (UInt_t i = 0; i < height; ++i, srcLine -= 4 * width, dstLine += 4 * width)
1074 std::copy(srcLine, srcLine + 4 * width, dstLine);
1075
1076 if (enableBlending) {
1079 }
1080
1082
1083 if (enableBlending)
1085
1086 //Restore raster pos.
1087 glRasterPos2d(oldPos[0], oldPos[1]);
1088 } else
1089 ::Error("TGLPadPainter::DrawPixels", "no pad found to draw");
1090}
1091
1092//Aux. functions - gradient and solid fill of arbitrary area.
1093
1094////////////////////////////////////////////////////////////////////////////////
1095///At the moment I assume both linear and radial gradients will work the same way -
1096///using a stencil buffer and some big rectangle(s) to fill with a gradient.
1097///Thus I have a 'common' part - the part responsible for a stencil test.
1098
1100{
1101 assert(n > 2 && "DrawPolygonWithGradient, invalid number of points");
1102 assert(x != nullptr && "DrawPolygonWithGradient, parameter 'x' is null");
1103 assert(y != nullptr && "DrawPolygonWithGradient, parameter 'y' is null");
1104
1105 auto grad = dynamic_cast<TColorGradient *>(gROOT->GetColor(fGlFillAtt.GetFillColor()));
1106 assert(grad != nullptr && "DrawPolygonWithGradient, the current fill color is not a gradient fill");
1107
1108 if (fLocked)
1109 return;
1110
1111 //Now, some magic!
1113
1114 //TODO: check that the state is restored back correctly after
1115 // we done with a gradient.
1116 //TODO: make sure that we have glDepthMask set to false in general!
1118
1119 glStencilFunc(GL_NEVER, 1, 0xFF);
1120 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);// draw 1s on test fail (always)
1121 //Draw stencil pattern
1122 glStencilMask(0xFF);
1124
1125 //Draw our polygon into the stencil buffer:
1126 DrawTesselation(n, x, y);
1127
1129 glStencilMask(0x00);
1130 //Draw where stencil's value is 0
1131 glStencilFunc(GL_EQUAL, 0, 0xFF);
1132 //Draw only where stencil's value is 1
1133 glStencilFunc(GL_EQUAL, 1, 0xFF);
1134
1135 //At the moment radial gradient is derived from linear - it was convenient
1136 //at some point, but in fact it was a bad idea. And now I have to
1137 //first check radial gradient.
1138 //TODO: TRadialGradient must inherit TColorGradient directly.
1139 const TRadialGradient * const rGrad = dynamic_cast<const TRadialGradient *>(grad);
1140 if (rGrad)
1141 DrawGradient(rGrad, n, x, y);
1142 else {
1143 const TLinearGradient * const lGrad = dynamic_cast<const TLinearGradient *>(grad);
1144 assert(lGrad != nullptr && "DrawPolygonWithGradient, unknown gradient type");
1145 DrawGradient(lGrad, n, x, y);
1146 }
1147}
1148
1149////////////////////////////////////////////////////////////////////////////////
1150
1152 const Double_t *xs, const Double_t *ys)
1153{
1154 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1155 assert(nPoints > 2 && "DrawGradient, invalid number of points");
1156 assert(xs != nullptr && "DrawGradient, parameter 'xs' is null");
1157 assert(ys != nullptr && "DrawGradient, parameter 'ys' is null");
1158
1160 ::Warning("TGLPadPainter::DrawGradient",
1161 "extended radial gradient is not supported");//yet?
1162 return;
1163 }
1164
1165 //TODO: check the polygon's bbox!
1166 const auto &bbox = Rgl::Pad::FindBoundingRect(nPoints, xs, ys);
1167 //
1168 auto center = grad->GetCenter();
1169 auto radius = grad->GetRadius();
1170 //Adjust the center and radius depending on coordinate mode.
1172 radius *= TMath::Max(bbox.fWidth, bbox.fHeight);
1173 center.fX = bbox.fWidth * center.fX + bbox.fXMin;
1174 center.fY = bbox.fHeight * center.fY + bbox.fYMin;
1175 } else {
1176 const auto w = gPad->GetX2() - gPad->GetX1();
1177 const auto h = gPad->GetY2() - gPad->GetY1();
1178
1179 radius *= TMath::Max(w, h);
1180 center.fX *= w;
1181 center.fY *= h;
1182 }
1183 //Now for the gradient fill we switch into pixel coordinates:
1184 const auto pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1185 const auto pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1186 //
1189 //A new ortho projection:
1192 //
1193 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1194 //
1196 center.fX = gPad->XtoPixel(center.fX);
1197 center.fY = pixelH - gPad->YtoPixel(center.fY);
1198
1199 Double_t maxR = 0.;
1200 {
1201 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1202 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1203 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1204 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1205 //Get the longest distance from the center to the bounding box vertices
1206 //(this will be the maximum possible radius):
1207 const Double_t maxDistX = TMath::Max(TMath::Abs(center.fX - xMin),
1208 TMath::Abs(center.fX - xMax));
1209 const Double_t maxDistY = TMath::Max(TMath::Abs(center.fY - yMin),
1210 TMath::Abs(center.fY - yMax));
1212 }
1213
1214 //If gradient 'stops inside the polygon', we use
1215 //the solid fill for the area outside of radial gradient:
1216 const Bool_t solidFillAfter = maxR > radius;
1217 //We emulate a radial gradient using triangles and linear gradient:
1218 //TODO: Can be something smarter? (btw even 100 seems to be enough)
1219 const UInt_t nSlices = 500;
1220
1221 const auto nColors = grad->GetNumberOfSteps();
1222 //+1 - the strip from the last color's position to radius,
1223 //and (probably) + 1 for solidFillAfter.
1224 const auto nCircles = nColors + 1 + solidFillAfter;
1225
1226 //TODO: can locations be outside of [0., 1.] ???
1227 //at the moment I assume the answer is NO, NEVER.
1228 const auto locations = grad->GetColorPositions();
1229 // * 2 below == x,y
1230 std::vector<Double_t> circles(nSlices * nCircles * 2);
1231 const Double_t angle = TMath::TwoPi() / nSlices;
1232
1233 //"Main" circles (for colors at locations[i]).
1234 for (UInt_t i = 0; i < nColors; ++i) {
1235 const auto circle = &circles[i * nSlices * 2];
1236 //TODO: either check locations here or somewhere else.
1237 const auto r = radius * locations[i];
1238 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1239 circle[j] = center.fX + r * TMath::Cos(angle * j);
1240 circle[j + 1] = center.fY + r * TMath::Sin(angle * j);
1241 }
1242 //The "closing" vertices:
1243 circle[(nSlices - 1) * 2] = circle[0];
1244 circle[(nSlices - 1) * 2 + 1] = circle[1];
1245 }
1246
1247 {
1248 //The strip between lastPos and radius:
1249 const auto circle = &circles[nColors * nSlices * 2];
1250 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1251 circle[j] = center.fX + radius * TMath::Cos(angle * j);
1252 circle[j + 1] = center.fY + radius * TMath::Sin(angle * j);
1253 }
1254
1255 circle[(nSlices - 1) * 2] = circle[0];
1256 circle[(nSlices - 1) * 2 + 1] = circle[1];
1257 }
1258
1259 if (solidFillAfter) {
1260 //The strip after the radius:
1261 const auto circle = &circles[(nCircles - 1) * nSlices * 2];
1262 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1263 circle[j] = center.fX + maxR * TMath::Cos(angle * j);
1264 circle[j + 1] = center.fY + maxR * TMath::Sin(angle * j);
1265 }
1266
1267 circle[(nSlices - 1) * 2] = circle[0];
1268 circle[(nSlices - 1) * 2 + 1] = circle[1];
1269 }
1270
1271 //Now we draw:
1272 //1) triangle fan in the center (from center to the locations[1],
1273 // with a solid fill).
1274 //2) quad strips for colors.
1275 //3) additional quad strip from the lastLocation to the radius
1276 //4) additional quad strip (if any) from the radius to maxR.
1277
1278 //RGBA values:
1279 const auto rgba = grad->GetColors();
1280
1282 //TODO?
1284
1285 //Probably a degenerated case. Maybe not.
1288 glVertex2d(center.fX, center.fY);
1289
1290 for (UInt_t i = 0, e = nSlices * 2; i < e; i += 2)
1291 glVertex2dv(&circles[i]);
1292
1293 glEnd();
1294
1295 //No auto for circles, explicit types to have const Double_t * const, not Duble_t * const.
1296 for (UInt_t i = 0; i < nColors - 1; ++i) {
1297 const Double_t * const inner = &circles[i * nSlices * 2];
1298 const auto innerRGBA = rgba + i * 4;
1299 const auto outerRGBA = rgba + (i + 1) * 4;
1300 const Double_t * const outer = &circles[(i + 1) * nSlices * 2];
1301
1303 }
1304
1305 //Probably degenerated strip.
1306 {
1307 const Double_t * const inner = &circles[nSlices * (nColors - 1) * 2];
1308 const auto solidRGBA = rgba + (nColors - 1) * 4;
1309 const Double_t * const outer = &circles[nSlices * nColors * 2];
1310
1312 }
1313
1314 if (solidFillAfter) {
1315 const Double_t * const inner = &circles[nSlices * nColors * 2];
1316 const auto solidRGBA = rgba + (nColors - 1) * 4;
1317 const Double_t * const outer = &circles[nSlices * (nColors + 1) * 2];
1318
1320 }
1321
1324}
1325
1326////////////////////////////////////////////////////////////////////////////////
1327
1329 const Double_t *x, const Double_t *y)
1330{
1331 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1332 assert(n > 2 && "DrawGradient, invalid number of points");
1333 assert(x != nullptr && "DrawGradient, parameter 'x' is null");
1334 assert(y != nullptr && "DrawGradient, parameter 'y' is null");
1335
1336 //Now we fill the whole scene with one big rectangle
1337 //(group of rectangles) with a gradient fill using
1338 //stencil test.
1339
1340 //Find a bounding rect.
1341 const auto &bbox = Rgl::Pad::FindBoundingRect(n, x, y);
1342 //TODO: check the bbox??
1343
1344 //For the gradient fill we switch into the
1345 //pixel coordinates.
1348
1349 //A new ortho projection:
1352
1353 const Double_t pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1354 const Double_t pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1355 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1356
1357 //A new modelview:
1360 //
1361 TColorGradient::Point start = grad->GetStart();
1362 TColorGradient::Point end = grad->GetEnd();
1363
1364 //Change gradient coordinates from 'NDC' to pad coords:
1366 {
1367 const Double_t w = gPad->GetX2() - gPad->GetX1();
1368 const Double_t h = gPad->GetY2() - gPad->GetY1();
1369
1370 start.fX = start.fX * w;
1371 start.fY = start.fY * h;
1372 end.fX = end.fX * w;
1373 end.fY = end.fY * h;
1374 } else {
1375 start.fX = start.fX * bbox.fWidth + bbox.fXMin;
1376 start.fY = start.fY * bbox.fHeight + bbox.fYMin;
1377 end.fX = end.fX * bbox.fWidth + bbox.fXMin;
1378 end.fY = end.fY * bbox.fHeight + bbox.fYMin;
1379 }
1380
1381 //TODO: with a radial fill we'll have to extract the code
1382 // below into the separate function/and have additional function
1383 // for a radial gradient.
1384 //Now from pad to pixels:
1385 start.fX = gPad->XtoPixel(start.fX);
1386 start.fY = pixelH - gPad->YtoPixel(start.fY);
1387 end.fX = gPad->XtoPixel(end.fX);
1388 end.fY = pixelH - gPad->YtoPixel(end.fY);
1389 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1390 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1391 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1392 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1393 //
1394
1395 //TODO: check all calculations!
1396
1397 //Get the longest distance from the start point to the bounding box vertices:
1398 const Double_t maxDistX = TMath::Max(TMath::Abs(start.fX - xMin), TMath::Abs(start.fX - xMax));
1399 const Double_t maxDistY = TMath::Max(TMath::Abs(start.fY - yMin), TMath::Abs(start.fY - yMax));
1400
1401 const Double_t startEndLength = TMath::Sqrt((end.fX - start.fX) * (end.fX - start.fX) +
1402 (end.fY - start.fY) * (end.fY - start.fY));
1405
1406 //Boxes with a gradients to emulate gradient fill with many colors:
1407 const Double_t * const colorPositions = grad->GetColorPositions();
1408 std::vector<Double_t> gradBoxes(grad->GetNumberOfSteps() + 2);
1409 gradBoxes[0] = start.fY - h;
1410 for (unsigned i = 1; i <= grad->GetNumberOfSteps(); ++i)
1411 gradBoxes[i] = startEndLength * colorPositions[i - 1] + start.fY;
1412
1413 gradBoxes[grad->GetNumberOfSteps() + 1] = start.fY + h;
1414
1415 //Rotation angle - gradient's axis:
1416 Double_t angle = TMath::ACos((startEndLength * (end.fY - start.fY)) /
1418 if (end.fX > start.fX)
1419 angle *= -1;
1420
1421 glTranslated(start.fX, start.fY, 0.);
1422 glRotated(angle, 0., 0., 1.);
1423 glTranslated(-start.fX, -start.fY, 0.);
1424 //
1425 const Double_t * const rgba = grad->GetColors();
1426
1427 const unsigned nEdges = gradBoxes.size();
1428 const unsigned nColors = grad->GetNumberOfSteps();
1429 const Double_t xLeft = start.fX - h, xRight = start.fX + h;
1430
1432 //TODO?
1434
1437 rgba + (nColors - 1) * 4, rgba + (nColors - 1) * 4);
1438
1439 for (unsigned i = 1; i < nEdges - 2; ++i)
1441 xRight, rgba + (i - 1) * 4, rgba + i * 4);
1442
1445}
1446
1447////////////////////////////////////////////////////////////////////////////////
1448
1450{
1451 assert(n > 2 && "DrawTesselation, invalid number of points");
1452 assert(x != nullptr && "DrawTesselation, parameter 'x' is null");
1453 assert(y != nullptr && "DrawTesselation, parameter 'y' is null");
1454
1455 //Data for a tesselator:
1456 fVs.resize(n * 3);
1457
1458 for (Int_t i = 0; i < n; ++i) {
1459 fVs[i * 3] = x[i];
1460 fVs[i * 3 + 1] = y[i];
1461 fVs[i * 3 + 2] = 0.;
1462 }
1463
1464 //TODO: A very primitive way to tesselate - check what
1465 //kind of polygons we can really have from TPad/TCanvas.
1467 gluBeginPolygon(t);
1469
1470 for (Int_t i = 0; i < n; ++i)
1471 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
1472
1473 gluEndPolygon(t);
1474}
1475
#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
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.
void SetTextAlign(UInt_t align)
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 SetDrawMode(Int_t device, Int_t mode) override
Set drawing mode for specified device.
void DrawPixels(const unsigned char *pixelData, UInt_t width, UInt_t height, Int_t dstX, Int_t dstY, Bool_t enableBlending) override
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 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.
void RestoreModelviewMatrix() const
Restore the modelview matrix.
std::vector< Double_t > fVs
Bool_t fIsHollowArea
void SaveProjectionMatrix() const
Save the projection matrix.
void DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2) override
Draw line segment.
Bool_t IsCocoa() const override
Returns true when cocoa backend is used.
void 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