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/// Set text attributes
137
139{
141
142 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
143 if (fWinContext && gVirtualX)
144 gVirtualX->SetAttText(fWinContext, att);
145}
146
147/*
148"Pixmap" part of TGLPadPainter.
149*/
150
151////////////////////////////////////////////////////////////////////////////////
152///Not required at the moment.
153
155{
156 // return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
157 return 0;
158}
159
160////////////////////////////////////////////////////////////////////////////////
161/// Resize a gVirtualX Pixmap.
162
164{
165 return gVirtualX->ResizePixmap(device, w, h);
166}
167
168////////////////////////////////////////////////////////////////////////////////
169/// Call gVirtualX->ClearWindow()
170
172{
173 gVirtualX->ClearWindow();
174}
175
176////////////////////////////////////////////////////////////////////////////////
177/// Returns true when cocoa backend is used
178
180{
181 return gVirtualX->InheritsFrom("TGCocoa");
182}
183
184////////////////////////////////////////////////////////////////////////////////
185///Not required at the moment.
186
187void TGLPadPainter::CopyDrawable(Int_t /* device */, Int_t /* px */, Int_t /* py */)
188{
189 // gVirtualX->CopyPixmapW(fWinContext, device, px, py);
190}
191
192////////////////////////////////////////////////////////////////////////////////
193///Not required at the moment.
194
196{
197 // gVirtualX->SelectWindow(device);
198 // gVirtualX->ClosePixmap();
199 fWinContext = 0;
200}
201
202////////////////////////////////////////////////////////////////////////////////
203///For gVirtualX this means select pixmap (or window)
204///and all subsequent drawings will go into
205///this pixmap. For OpenGL this means the change of
206///coordinate system and viewport.
207
209{
210 auto pad = dynamic_cast<TPad *>(gPad);
211 if (!fWinContext && pad)
212 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
213
214 if (fLocked)
215 return;
216
217 if (pad) {
218 // GL painter does not use proper id for sub-pads (see CreateDrawable)
219 // so one always use canvas ID to execute TVirtualX-specific commands
220 Int_t px = 0, py = 0;
221
222 pad->XYtoAbsPixel(pad->GetX1(), pad->GetY1(), px, py);
223
224 py = gPad->GetWh() - py;
225 //
228
229 glViewport(GLint(px * scale), GLint(py * scale),
230 GLsizei(gPad->GetWw() * pad->GetAbsWNDC() * scale),
231 GLsizei(gPad->GetWh() * pad->GetAbsHNDC() * scale));
232
235 glOrtho(pad->GetX1(), pad->GetX2(), pad->GetY1(), pad->GetY2(), -10., 10.);
236
239 glTranslated(0., 0., -1.);
240 } else {
241 ::Error("TGLPadPainter::SelectDrawable",
242 "function was called not from TPad or TCanvas code\n");
243 throw std::runtime_error("");
244 }
245}
246
247////////////////////////////////////////////////////////////////////////////////
248/// Call low-level update of selected drawable, redirect to gVirtualX.
249
251{
252 if (fWinContext)
253 gVirtualX->UpdateWindowW(fWinContext, mode);
254}
255
256
257////////////////////////////////////////////////////////////////////////////////
258/// Set drawing mode for specified device
259
261{
262 auto ctxt = fWinContext;
263 if (device)
264 ctxt = gVirtualX->GetWindowContext(device);
265 if (ctxt)
266 gVirtualX->SetDrawModeW(ctxt, (TVirtualX::EDrawMode) mode);
267}
268
269////////////////////////////////////////////////////////////////////////////////
270///Init gl-pad painter:
271///1. 2D painter does not use depth test, should not modify
272/// depth-buffer content (except initial cleanup).
273///2. Disable cull face.
274///3. Disable lighting.
275///4. Set viewport (to the whole canvas area).
276///5. Set camera.
277///6. Unlock painter.
278
280{
281 static bool gl_init = false;
282 if (!gl_init) {
284 if (version == 0)
285 Warning("TGLPadPainter::InitPainter", "GL initalization failed.");
286 else if (gDebug > 0)
287 Info("TGLPadPainter::InitPainter", "GL initalization successful.");
288 gl_init = true;
289 }
293
294 //Clear the buffer
295 glViewport(0, 0, GLsizei(gPad->GetWw()), GLsizei(gPad->GetWh()));
296
298 glClearColor(1.,1.,1.,1.);
301
304
305 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
306
309 glTranslated(0., 0., -1.);
310
311 fLocked = kFALSE;
312}
313
314////////////////////////////////////////////////////////////////////////////////
315///When TPad::Range for gPad is called, projection
316///must be changed in OpenGL.
317
319{
320 if (fLocked) return;
321
324
325 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
326
328}
329
330////////////////////////////////////////////////////////////////////////////////
331///Locked state of painter means, that
332///GL context can be invalid, so no GL calls
333///can be executed.
334
336{
337 if (fLocked) return;
338
339 glFinish();
340 fLocked = kTRUE;
341}
342
343/*
3442D primitives.
345*/
346
348
349////////////////////////////////////////////////////////////////////////////////
350///Draw line segment.
351
353{
354 if (fLocked) {
355 //GL pad painter can be called in non-standard situation:
356 //not from TPad::Paint, but
357 //from TView3D::ExecuteRotateView. This means in fact,
358 //that TView3D wants to draw itself in a XOR mode, via
359 //gVirtualX.
360 // TODO: only here set line attributes to virtual x
361 if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) {
362 gVirtualX->DrawLineW(fWinContext,
363 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
364 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2));
365 }
366
367 return;
368 }
369
371
372 glBegin(GL_LINES);
373 glVertex2d(x1, y1);
374 glVertex2d(x2, y2);
375 glEnd();
376
378 Double_t pointSize = GetAttLine().GetLineWidth();
384 glBegin(GL_POINTS);
385
386 glVertex2d(x1, y1);
387 glVertex2d(x2, y2);
388
389 glEnd();
390 glPointSize(1.f);
391 }
392
393}
394
395////////////////////////////////////////////////////////////////////////////////
396///Draw line segment in NDC coordinates.
397
399{
400 if (fLocked) {
401 // this code used when crosshair cursor is drawn
402 if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) {
403 // TODO: only here set line attributes to virtual x
404 gVirtualX->DrawLineW(fWinContext,
405 gPad->UtoAbsPixel(u1), gPad->VtoAbsPixel(v1),
406 gPad->UtoAbsPixel(u2), gPad->VtoAbsPixel(v2));
407 }
408 return;
409 }
410
412 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
413 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
414
415 glBegin(GL_LINES);
416 glVertex2d(gPad->GetX1() + u1 * xRange, gPad->GetY1() + v1 * yRange);
417 glVertex2d(gPad->GetX1() + u2 * xRange, gPad->GetY1() + v2 * yRange);
418 glEnd();
419}
420
421////////////////////////////////////////////////////////////////////////////////
422///Draw filled or hollow box.
423
425{
426 if (fLocked) {
427 //GL pad painter can be called in non-standard situation:
428 //not from TPad::Paint, but
429 //from TView3D::ExecuteRotateView. This means in fact,
430 //that TView3D wants to draw itself in a XOR mode, via
431 //gVirtualX.
432 // TODO: only here set line attributes to virtual x
433 if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) {
434 gVirtualX->DrawBoxW(fWinContext,
435 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
436 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2),
438 }
439 return;
440 }
441
443 Double_t xs[] = {x1, x2, x2, x1};
444 Double_t ys[] = {y1, y1, y2, y2};
446 return;
447 }
448
449 if (mode == kHollow) {
451 //
453 glRectd(x1, y1, x2, y2);
455 glLineWidth(1.f);
456 } else {
457 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE, &fGlFillAtt);//Set filling parameters.
458 glRectd(x1, y1, x2, y2);
459 }
460}
461
462////////////////////////////////////////////////////////////////////////////////
463///Draw tesselated polygon (probably, outline only).
464
466{
467 assert(x != nullptr && "DrawFillArea, parameter 'x' is null");
468 assert(y != nullptr && "DrawFillArea, parameter 'y' is null");
469
470 if (fLocked)
471 return;
472
473 if (n < 3) {
474 ::Error("TGLPadPainter::DrawFillArea",
475 "invalid number of points in a polygon");
476 return;
477 }
478
480 return DrawPolygonWithGradient(n, x, y);
481
482 if (fFullyTransparent) {
484 return DrawPolyLine(n, x, y);
485 }
486
488 DrawTesselation(n, x, y);
489}
490
491////////////////////////////////////////////////////////////////////////////////
492///Draw tesselated polygon (never called, probably, since TPad::PaintFillArea for floats
493///is deprecated).
494
496{
497 if (fLocked) return;
498
499 if (fFullyTransparent) {
501 return DrawPolyLine(n, x, y);
502 }
503
504 fVs.resize(n * 3);
505
506 for (Int_t i = 0; i < n; ++i) {
507 fVs[i * 3] = x[i];
508 fVs[i * 3 + 1] = y[i];
509 }
510
512
516
517 for (Int_t i = 0; i < n; ++i)
518 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
519
520
521 gluEndPolygon(t);
522}
523
524////////////////////////////////////////////////////////////////////////////////
525///Draw poly-line in user coordinates.
526
528{
529 if (fLocked) return;
530
532
533 glBegin(GL_LINE_STRIP);
534
535 for (Int_t i = 0; i < n; ++i)
536 glVertex2d(x[i], y[i]);
537
538 if (fIsHollowArea) {
539 glVertex2d(x[0], y[0]);
541 }
542 glEnd();
543
545 Double_t pointSize = GetAttLine().GetLineWidth();
551 glBegin(GL_POINTS);
552
553 for (Int_t i = 0; i < n; ++i)
554 glVertex2d(x[i], y[i]);
555
556 glEnd();
557 glPointSize(1.f);
558 }
559}
560
561////////////////////////////////////////////////////////////////////////////////
562///Never called?
563
565{
566 if (fLocked) return;
567
569
570 glBegin(GL_LINE_STRIP);
571
572 for (Int_t i = 0; i < n; ++i)
573 glVertex2f(x[i], y[i]);
574
575 if (fIsHollowArea) {
576 glVertex2f(x[0], y[0]);
578 }
579
580 glEnd();
581}
582
583////////////////////////////////////////////////////////////////////////////////
584///Poly line in NDC.
585
587{
588 if (fLocked) return;
589
591 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
592 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
593 const Double_t x1 = gPad->GetX1(), y1 = gPad->GetY1();
594
595 glBegin(GL_LINE_STRIP);
596
597 for (Int_t i = 0; i < n; ++i)
598 glVertex2d(x1 + u[i] * xRange, y1 + v[i] * yRange);
599
600 glEnd();
601}
602
603namespace {
604
605//Aux. function.
606template<class ValueType>
607void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst);
608
609}
610
611////////////////////////////////////////////////////////////////////////////////
612///Poly-marker.
613
615{
616 if (fLocked) return;
617
620}
621
622////////////////////////////////////////////////////////////////////////////////
623///Poly-marker.
624
626{
627 if (fLocked) return;
628
631}
632
633////////////////////////////////////////////////////////////////////////////////
634///Poly-marker.
635
637{
638 if (fLocked) return;
639
642 //
643 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
644 //
646 //
648
649 Float_t rgba[4] = {};
653
654
657
658 fMarker.SetMarkerSizeWidth(GetAttMarker().GetMarkerSize(), w);
659
660 const TPoint *xy = &fPoly[0];
662 const UInt_t n = UInt_t(fPoly.size());
663 switch (markerStyle) {
664 case kDot:
666 break;
667 case kPlus:
669 break;
670 case kStar:
671 case 31:
673 break;
674 case kCircle:
675 case kOpenCircle:
677 break;
678 case kMultiply:
679 fMarker.DrawX(n, xy);
680 break;
681 case kFullDotSmall://"Full dot small"
683 break;
684 case kFullDotMedium:
686 break;
687 case kFullDotLarge:
688 case kFullCircle:
690 break;
691 case kFullSquare:
693 break;
694 case kFullTriangleUp:
696 break;
699 break;
700 case kOpenSquare:
704 break;
705 case kOpenTriangleUp:
709 break;
710 case kOpenDiamond:
712 break;
713 case kOpenCross:
715 break;
716 case kFullStar:
718 break;
719 case kOpenStar:
721 break;
724 break;
725 case kFullDiamond:
727 break;
728 case kFullCross:
730 break;
733 break;
736 break;
739 break;
740 case kOctagonCross:
742 break;
745 break;
748 break;
751 break;
754 break;
757 break;
760 break;
763 break;
764 case kOpenCrossX:
766 break;
767 case kFullCrossX:
769 break;
770 case kFourSquaresX:
772 break;
773 case kFourSquaresPlus:
775 break;
776 }
777
780 glLineWidth(1.f);
781}
782
783////////////////////////////////////////////////////////////////////////////////
784
785template<class Char>
787{
789
791 //
792 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
793 //
795
796 Float_t rgba[4] = {};
799
800 //10 is the first valid font index.
801 //20 is FreeSerifBold, as in TTF.cxx and in TGLFontManager.cxx.
802 //shift - is the shift to access "extended" fonts.
804
806 if (fontIndex / 10 + shift > TGLFontManager::GetFontFileArray()->GetEntries())
807 fontIndex = 20 + shift * 10;
808 else
809 fontIndex += shift * 10;
810
812
813 fFM.RegisterFont(TMath::Max(Int_t(GetAttText().GetTextSize()) - 1, 10),//kTexture does not work if size < 10.
816 fF.PreRender();
817
818 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
819 fF.Render(text, gPad->XtoPixel(x), padH - gPad->YtoPixel(y), GetTextAngle(), GetTextMagnitude());
820
821 fF.PostRender();
823
825}
826
827////////////////////////////////////////////////////////////////////////////////
828///Draw text. This operation is especially
829///dangerous if in locked state -
830///ftgl will assert on zero texture size
831///(which is result of bad GL context).
832
834{
835 if (fLocked) return;
836
837 if (!GetAttText().GetTextSize())
838 return;
839
841}
842
843////////////////////////////////////////////////////////////////////////////////
844///Draw text. This operation is especially
845///dangerous if in locked state -
846///ftgl will assert on zero texture size
847///(which is result of bad GL context).
848
850{
851 if (fLocked) return;
852
853 if (!GetAttText().GetTextSize())
854 return;
855
857}
858
859////////////////////////////////////////////////////////////////////////////////
860///Draw text in NDC. This operation is especially
861///dangerous if in locked state -
862///ftgl will assert on zero texture size
863///(which is result of bad GL context).
864
866{
867 if (fLocked) return;
868
869 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
870 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
871 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
872}
873
874////////////////////////////////////////////////////////////////////////////////
875///Draw text in NDC. This operation is especially
876///dangerous if in locked state -
877///ftgl will assert on zero texture size
878///(which is result of bad GL context).
879
881{
882 if (fLocked) return;
883
884 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
885 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
886 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
887}
888
889////////////////////////////////////////////////////////////////////////////////
890///Save the projection matrix.
891///Attention! GL_PROJECTION will become the current matrix
892///after this call!
893
899
900////////////////////////////////////////////////////////////////////////////////
901///Restore the projection matrix.
902///Attention! GL_PROJECTION will become the current matrix
903///after this call!
904
910
911////////////////////////////////////////////////////////////////////////////////
912///Save the modelview matrix.
913///Attention! GL_MODELVIEW will become the current matrix
914///after this call!
915
921
922////////////////////////////////////////////////////////////////////////////////
923///Restore the modelview matrix.
924///Attention! GL_MODELVIEW will become the current matrix
925///after this call!
926
932
933////////////////////////////////////////////////////////////////////////////////
934///Extract and save the current viewport.
935
940
941////////////////////////////////////////////////////////////////////////////////
942///Restore the saved viewport.
943
945{
946 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
947}
948
949////////////////////////////////////////////////////////////////////////////////
950/// Using TImage save frame-buffer contents as a picture.
951
952void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
953{
954 auto canvas = pad->GetCanvas();
955 if (!canvas)
956 return;
957
958 canvas->Flush();
959
960 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
963 //In case GL_BGRA is not in gl.h (old windows' gl) - comment/uncomment lines.
964 //glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_BGRA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
965 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
966
967 std::unique_ptr<TImage> image(TImage::Create());
968 if (!image.get()) {
969 ::Error("TGLPadPainter::SaveImage", "TImage creation failed");
970 return;
971 }
972
973 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
974 UInt_t *argb = image->GetArgbArray();
975
976 if (!argb) {
977 ::Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
978 return;
979 }
980
981 const Int_t nLines = canvas->GetWh();
982 const Int_t nPixels = canvas->GetWw();
983
984 for (Int_t i = 0; i < nLines; ++i) {
985 Int_t base = (nLines - 1 - i) * nPixels;
986 for (Int_t j = 0; j < nPixels; ++j, ++base) {
987 //Uncomment/comment if you don't have GL_BGRA.
988
989 const UInt_t pix = buff[base];
990 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
991 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
992
993 //argb[i * nPixels + j] = buff[base];
994 argb[i * nPixels + j] = bgra;
995 }
996 }
997
998 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
999}
1000
1001////////////////////////////////////////////////////////////////////////////////
1002
1005{
1006 if (fLocked)
1007 return;
1008
1009 if (!pixelData) {
1010 //I'd prefer an assert.
1011 ::Error("TGLPadPainter::DrawPixels", "pixel data is null");
1012 return;
1013 }
1014
1015 if (std::numeric_limits<UInt_t>::digits >= 32) {
1016 //TASImage uses bit 31 as ...
1017 //alpha channel flag! FUUUUUUUUUUUUU ..... !!!
1018 CLRBIT(width, 31);
1019 CLRBIT(height, 31);
1020 }
1021
1022 if (!width) {
1023 //Assert is better.
1024 ::Error("TGLPadPainter::DrawPixels", "invalid width");
1025 return;
1026 }
1027
1028 if (!height) {
1029 //Assert is better.
1030 ::Error("TGLPadPainter::DrawPixels", "invalid height");
1031 return;
1032 }
1033
1034 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
1035 //TASImage passes pixel coordinates in pad's pixmap coordinate space.
1036 //While glRasterPosX said to work with 'window' coordinates,
1037 //that's a lie :) it does not :)
1038
1039 const Double_t rasterX = Double_t(dstX) / (pad->GetAbsWNDC() * pad->GetWw()) *
1040 (pad->GetX2() - pad->GetX1()) + pad->GetX1();
1041
1042 const Double_t yRange = pad->GetY2() - pad->GetY1();
1043 const Double_t rasterY = yRange - Double_t(dstY + height) / (pad->GetAbsHNDC() * pad->GetWh()) * yRange +
1044 pad->GetY1();
1045
1046 GLdouble oldPos[4] = {};
1047 //Save the previous raster pos.
1049
1051 //Stupid asimage provides us upside-down image.
1052 std::vector<unsigned char> upsideDownImage(4 * width * height);
1053 const unsigned char *srcLine = pixelData + 4 * width * (height - 1);
1054 unsigned char *dstLine = &upsideDownImage[0];
1055 for (UInt_t i = 0; i < height; ++i, srcLine -= 4 * width, dstLine += 4 * width)
1056 std::copy(srcLine, srcLine + 4 * width, dstLine);
1057
1058 if (enableBlending) {
1061 }
1062
1064
1065 if (enableBlending)
1067
1068 //Restore raster pos.
1069 glRasterPos2d(oldPos[0], oldPos[1]);
1070 } else
1071 ::Error("TGLPadPainter::DrawPixels", "no pad found to draw");
1072}
1073
1074//Aux. functions - gradient and solid fill of arbitrary area.
1075
1076////////////////////////////////////////////////////////////////////////////////
1077///At the moment I assume both linear and radial gradients will work the same way -
1078///using a stencil buffer and some big rectangle(s) to fill with a gradient.
1079///Thus I have a 'common' part - the part responsible for a stencil test.
1080
1082{
1083 assert(n > 2 && "DrawPolygonWithGradient, invalid number of points");
1084 assert(x != nullptr && "DrawPolygonWithGradient, parameter 'x' is null");
1085 assert(y != nullptr && "DrawPolygonWithGradient, parameter 'y' is null");
1086
1087 auto grad = dynamic_cast<TColorGradient *>(gROOT->GetColor(fGlFillAtt.GetFillColor()));
1088 assert(grad != nullptr && "DrawPolygonWithGradient, the current fill color is not a gradient fill");
1089
1090 if (fLocked)
1091 return;
1092
1093 //Now, some magic!
1095
1096 //TODO: check that the state is restored back correctly after
1097 // we done with a gradient.
1098 //TODO: make sure that we have glDepthMask set to false in general!
1100
1101 glStencilFunc(GL_NEVER, 1, 0xFF);
1102 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);// draw 1s on test fail (always)
1103 //Draw stencil pattern
1104 glStencilMask(0xFF);
1106
1107 //Draw our polygon into the stencil buffer:
1108 DrawTesselation(n, x, y);
1109
1111 glStencilMask(0x00);
1112 //Draw where stencil's value is 0
1113 glStencilFunc(GL_EQUAL, 0, 0xFF);
1114 //Draw only where stencil's value is 1
1115 glStencilFunc(GL_EQUAL, 1, 0xFF);
1116
1117 //At the moment radial gradient is derived from linear - it was convenient
1118 //at some point, but in fact it was a bad idea. And now I have to
1119 //first check radial gradient.
1120 //TODO: TRadialGradient must inherit TColorGradient directly.
1121 const TRadialGradient * const rGrad = dynamic_cast<const TRadialGradient *>(grad);
1122 if (rGrad)
1123 DrawGradient(rGrad, n, x, y);
1124 else {
1125 const TLinearGradient * const lGrad = dynamic_cast<const TLinearGradient *>(grad);
1126 assert(lGrad != nullptr && "DrawPolygonWithGradient, unknown gradient type");
1127 DrawGradient(lGrad, n, x, y);
1128 }
1129}
1130
1131////////////////////////////////////////////////////////////////////////////////
1132
1134 const Double_t *xs, const Double_t *ys)
1135{
1136 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1137 assert(nPoints > 2 && "DrawGradient, invalid number of points");
1138 assert(xs != nullptr && "DrawGradient, parameter 'xs' is null");
1139 assert(ys != nullptr && "DrawGradient, parameter 'ys' is null");
1140
1142 ::Warning("TGLPadPainter::DrawGradient",
1143 "extended radial gradient is not supported");//yet?
1144 return;
1145 }
1146
1147 //TODO: check the polygon's bbox!
1148 const auto &bbox = Rgl::Pad::FindBoundingRect(nPoints, xs, ys);
1149 //
1150 auto center = grad->GetCenter();
1151 auto radius = grad->GetRadius();
1152 //Adjust the center and radius depending on coordinate mode.
1154 radius *= TMath::Max(bbox.fWidth, bbox.fHeight);
1155 center.fX = bbox.fWidth * center.fX + bbox.fXMin;
1156 center.fY = bbox.fHeight * center.fY + bbox.fYMin;
1157 } else {
1158 const auto w = gPad->GetX2() - gPad->GetX1();
1159 const auto h = gPad->GetY2() - gPad->GetY1();
1160
1161 radius *= TMath::Max(w, h);
1162 center.fX *= w;
1163 center.fY *= h;
1164 }
1165 //Now for the gradient fill we switch into pixel coordinates:
1166 const auto pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1167 const auto pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1168 //
1171 //A new ortho projection:
1174 //
1175 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1176 //
1178 center.fX = gPad->XtoPixel(center.fX);
1179 center.fY = pixelH - gPad->YtoPixel(center.fY);
1180
1181 Double_t maxR = 0.;
1182 {
1183 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1184 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1185 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1186 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1187 //Get the longest distance from the center to the bounding box vertices
1188 //(this will be the maximum possible radius):
1189 const Double_t maxDistX = TMath::Max(TMath::Abs(center.fX - xMin),
1190 TMath::Abs(center.fX - xMax));
1191 const Double_t maxDistY = TMath::Max(TMath::Abs(center.fY - yMin),
1192 TMath::Abs(center.fY - yMax));
1194 }
1195
1196 //If gradient 'stops inside the polygon', we use
1197 //the solid fill for the area outside of radial gradient:
1198 const Bool_t solidFillAfter = maxR > radius;
1199 //We emulate a radial gradient using triangles and linear gradient:
1200 //TODO: Can be something smarter? (btw even 100 seems to be enough)
1201 const UInt_t nSlices = 500;
1202
1203 const auto nColors = grad->GetNumberOfSteps();
1204 //+1 - the strip from the last color's position to radius,
1205 //and (probably) + 1 for solidFillAfter.
1206 const auto nCircles = nColors + 1 + solidFillAfter;
1207
1208 //TODO: can locations be outside of [0., 1.] ???
1209 //at the moment I assume the answer is NO, NEVER.
1210 const auto locations = grad->GetColorPositions();
1211 // * 2 below == x,y
1212 std::vector<Double_t> circles(nSlices * nCircles * 2);
1213 const Double_t angle = TMath::TwoPi() / nSlices;
1214
1215 //"Main" circles (for colors at locations[i]).
1216 for (UInt_t i = 0; i < nColors; ++i) {
1217 const auto circle = &circles[i * nSlices * 2];
1218 //TODO: either check locations here or somewhere else.
1219 const auto r = radius * locations[i];
1220 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1221 circle[j] = center.fX + r * TMath::Cos(angle * j);
1222 circle[j + 1] = center.fY + r * TMath::Sin(angle * j);
1223 }
1224 //The "closing" vertices:
1225 circle[(nSlices - 1) * 2] = circle[0];
1226 circle[(nSlices - 1) * 2 + 1] = circle[1];
1227 }
1228
1229 {
1230 //The strip between lastPos and radius:
1231 const auto circle = &circles[nColors * nSlices * 2];
1232 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1233 circle[j] = center.fX + radius * TMath::Cos(angle * j);
1234 circle[j + 1] = center.fY + radius * TMath::Sin(angle * j);
1235 }
1236
1237 circle[(nSlices - 1) * 2] = circle[0];
1238 circle[(nSlices - 1) * 2 + 1] = circle[1];
1239 }
1240
1241 if (solidFillAfter) {
1242 //The strip after the radius:
1243 const auto circle = &circles[(nCircles - 1) * nSlices * 2];
1244 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1245 circle[j] = center.fX + maxR * TMath::Cos(angle * j);
1246 circle[j + 1] = center.fY + maxR * TMath::Sin(angle * j);
1247 }
1248
1249 circle[(nSlices - 1) * 2] = circle[0];
1250 circle[(nSlices - 1) * 2 + 1] = circle[1];
1251 }
1252
1253 //Now we draw:
1254 //1) triangle fan in the center (from center to the locations[1],
1255 // with a solid fill).
1256 //2) quad strips for colors.
1257 //3) additional quad strip from the lastLocation to the radius
1258 //4) additional quad strip (if any) from the radius to maxR.
1259
1260 //RGBA values:
1261 const auto rgba = grad->GetColors();
1262
1264 //TODO?
1266
1267 //Probably a degenerated case. Maybe not.
1270 glVertex2d(center.fX, center.fY);
1271
1272 for (UInt_t i = 0, e = nSlices * 2; i < e; i += 2)
1273 glVertex2dv(&circles[i]);
1274
1275 glEnd();
1276
1277 //No auto for circles, explicit types to have const Double_t * const, not Duble_t * const.
1278 for (UInt_t i = 0; i < nColors - 1; ++i) {
1279 const Double_t * const inner = &circles[i * nSlices * 2];
1280 const auto innerRGBA = rgba + i * 4;
1281 const auto outerRGBA = rgba + (i + 1) * 4;
1282 const Double_t * const outer = &circles[(i + 1) * nSlices * 2];
1283
1285 }
1286
1287 //Probably degenerated strip.
1288 {
1289 const Double_t * const inner = &circles[nSlices * (nColors - 1) * 2];
1290 const auto solidRGBA = rgba + (nColors - 1) * 4;
1291 const Double_t * const outer = &circles[nSlices * nColors * 2];
1292
1294 }
1295
1296 if (solidFillAfter) {
1297 const Double_t * const inner = &circles[nSlices * nColors * 2];
1298 const auto solidRGBA = rgba + (nColors - 1) * 4;
1299 const Double_t * const outer = &circles[nSlices * (nColors + 1) * 2];
1300
1302 }
1303
1306}
1307
1308////////////////////////////////////////////////////////////////////////////////
1309
1311 const Double_t *x, const Double_t *y)
1312{
1313 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1314 assert(n > 2 && "DrawGradient, invalid number of points");
1315 assert(x != nullptr && "DrawGradient, parameter 'x' is null");
1316 assert(y != nullptr && "DrawGradient, parameter 'y' is null");
1317
1318 //Now we fill the whole scene with one big rectangle
1319 //(group of rectangles) with a gradient fill using
1320 //stencil test.
1321
1322 //Find a bounding rect.
1323 const auto &bbox = Rgl::Pad::FindBoundingRect(n, x, y);
1324 //TODO: check the bbox??
1325
1326 //For the gradient fill we switch into the
1327 //pixel coordinates.
1330
1331 //A new ortho projection:
1334
1335 const Double_t pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1336 const Double_t pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1337 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1338
1339 //A new modelview:
1342 //
1343 TColorGradient::Point start = grad->GetStart();
1344 TColorGradient::Point end = grad->GetEnd();
1345
1346 //Change gradient coordinates from 'NDC' to pad coords:
1348 {
1349 const Double_t w = gPad->GetX2() - gPad->GetX1();
1350 const Double_t h = gPad->GetY2() - gPad->GetY1();
1351
1352 start.fX = start.fX * w;
1353 start.fY = start.fY * h;
1354 end.fX = end.fX * w;
1355 end.fY = end.fY * h;
1356 } else {
1357 start.fX = start.fX * bbox.fWidth + bbox.fXMin;
1358 start.fY = start.fY * bbox.fHeight + bbox.fYMin;
1359 end.fX = end.fX * bbox.fWidth + bbox.fXMin;
1360 end.fY = end.fY * bbox.fHeight + bbox.fYMin;
1361 }
1362
1363 //TODO: with a radial fill we'll have to extract the code
1364 // below into the separate function/and have additional function
1365 // for a radial gradient.
1366 //Now from pad to pixels:
1367 start.fX = gPad->XtoPixel(start.fX);
1368 start.fY = pixelH - gPad->YtoPixel(start.fY);
1369 end.fX = gPad->XtoPixel(end.fX);
1370 end.fY = pixelH - gPad->YtoPixel(end.fY);
1371 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1372 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1373 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1374 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1375 //
1376
1377 //TODO: check all calculations!
1378
1379 //Get the longest distance from the start point to the bounding box vertices:
1380 const Double_t maxDistX = TMath::Max(TMath::Abs(start.fX - xMin), TMath::Abs(start.fX - xMax));
1381 const Double_t maxDistY = TMath::Max(TMath::Abs(start.fY - yMin), TMath::Abs(start.fY - yMax));
1382
1383 const Double_t startEndLength = TMath::Sqrt((end.fX - start.fX) * (end.fX - start.fX) +
1384 (end.fY - start.fY) * (end.fY - start.fY));
1387
1388 //Boxes with a gradients to emulate gradient fill with many colors:
1389 const Double_t * const colorPositions = grad->GetColorPositions();
1390 std::vector<Double_t> gradBoxes(grad->GetNumberOfSteps() + 2);
1391 gradBoxes[0] = start.fY - h;
1392 for (unsigned i = 1; i <= grad->GetNumberOfSteps(); ++i)
1393 gradBoxes[i] = startEndLength * colorPositions[i - 1] + start.fY;
1394
1395 gradBoxes[grad->GetNumberOfSteps() + 1] = start.fY + h;
1396
1397 //Rotation angle - gradient's axis:
1398 Double_t angle = TMath::ACos((startEndLength * (end.fY - start.fY)) /
1400 if (end.fX > start.fX)
1401 angle *= -1;
1402
1403 glTranslated(start.fX, start.fY, 0.);
1404 glRotated(angle, 0., 0., 1.);
1405 glTranslated(-start.fX, -start.fY, 0.);
1406 //
1407 const Double_t * const rgba = grad->GetColors();
1408
1409 const unsigned nEdges = gradBoxes.size();
1410 const unsigned nColors = grad->GetNumberOfSteps();
1411 const Double_t xLeft = start.fX - h, xRight = start.fX + h;
1412
1414 //TODO?
1416
1419 rgba + (nColors - 1) * 4, rgba + (nColors - 1) * 4);
1420
1421 for (unsigned i = 1; i < nEdges - 2; ++i)
1423 xRight, rgba + (i - 1) * 4, rgba + i * 4);
1424
1427}
1428
1429////////////////////////////////////////////////////////////////////////////////
1430
1432{
1433 assert(n > 2 && "DrawTesselation, invalid number of points");
1434 assert(x != nullptr && "DrawTesselation, parameter 'x' is null");
1435 assert(y != nullptr && "DrawTesselation, parameter 'y' is null");
1436
1437 //Data for a tesselator:
1438 fVs.resize(n * 3);
1439
1440 for (Int_t i = 0; i < n; ++i) {
1441 fVs[i * 3] = x[i];
1442 fVs[i * 3 + 1] = y[i];
1443 fVs[i * 3 + 2] = 0.;
1444 }
1445
1446 //TODO: A very primitive way to tesselate - check what
1447 //kind of polygons we can really have from TPad/TCanvas.
1449 gluBeginPolygon(t);
1451
1452 for (Int_t i = 0; i < n; ++i)
1453 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
1454
1455 gluEndPolygon(t);
1456}
1457
1458
1459//Aux. functions.
1460namespace {
1461
1462template<class ValueType>
1463void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst)
1464{
1465 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
1466
1467 dst.resize(n);
1468 for (Int_t i = 0; i < n; ++i) {
1469 dst[i].fX = gPad->XtoPixel(x[i]);
1470 dst[i].fY = padH - gPad->YtoPixel(y[i]);
1471 }
1472}
1473
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 Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
#define CLRBIT(n, i)
Definition Rtypes.h:93
@ kOpenDoubleDiamond
Definition TAttMarker.h:68
@ kStar
Definition TAttMarker.h:58
@ kFullDotLarge
Definition TAttMarker.h:59
@ kFullDoubleDiamond
Definition TAttMarker.h:68
@ kOpenFourTrianglesX
Definition TAttMarker.h:67
@ kOpenSquare
Definition TAttMarker.h:61
@ kFullThreeTriangles
Definition TAttMarker.h:66
@ kOpenTriangleUp
Definition TAttMarker.h:62
@ kFourSquaresPlus
Definition TAttMarker.h:71
@ kFullDotSmall
Definition TAttMarker.h:59
@ kFullDotMedium
Definition TAttMarker.h:59
@ kOpenTriangleDown
Definition TAttMarker.h:63
@ kOpenThreeTriangles
Definition TAttMarker.h:65
@ kFullCrossX
Definition TAttMarker.h:70
@ kFullFourTrianglesX
Definition TAttMarker.h:67
@ kFullTriangleDown
Definition TAttMarker.h:61
@ kCircle
Definition TAttMarker.h:58
@ kOpenCrossX
Definition TAttMarker.h:70
@ kFullFourTrianglesPlus
Definition TAttMarker.h:69
@ kFullSquare
Definition TAttMarker.h:60
@ kOpenSquareDiagonal
Definition TAttMarker.h:65
@ kFullStar
Definition TAttMarker.h:63
@ kOpenDiamond
Definition TAttMarker.h:62
@ kFullTriangleUp
Definition TAttMarker.h:60
@ kOpenDiamondCross
Definition TAttMarker.h:64
@ kOpenFourTrianglesPlus
Definition TAttMarker.h:69
@ kMultiply
Definition TAttMarker.h:58
@ kPlus
Definition TAttMarker.h:58
@ kOctagonCross
Definition TAttMarker.h:66
@ kFullCircle
Definition TAttMarker.h:60
@ kDot
Definition TAttMarker.h:58
@ kOpenCross
Definition TAttMarker.h:62
@ kFourSquaresX
Definition TAttMarker.h:70
@ kOpenCircle
Definition TAttMarker.h:61
@ kFullCross
Definition TAttMarker.h:64
@ kOpenStar
Definition TAttMarker.h:63
@ kFullDiamond
Definition TAttMarker.h:64
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
const Double_t lineWidthTS
#define GL_BGRA
Definition TGLViewer.cxx:61
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void pix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint xy
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t width
Option_t Option_t TPoint TPoint percent
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint DrawText
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
Option_t Option_t TPoint TPoint const char text
Option_t Option_t TPoint TPoint const char y1
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:783
#define gROOT
Definition TROOT.h:426
#define gPad
#define gVirtualX
Definition TVirtualX.h:368
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 ...
Text Attributes class.
Definition TAttText.h:21
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 SetAttText(const TAttText &att) override
Set text attributes.
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 DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2) override
Draw line segment in NDC coordinates.
WinContext_t fWinContext
std::vector< TPoint > fPoly
void DrawTextHelper(Double_t x, Double_t y, const Char_t *text, ETextMode mode)
void DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EBoxMode mode) override
Draw filled or hollow box.
void 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...
void InvalidateCS() override
When TPad::Range for gPad is called, projection must be changed in OpenGL.
void ClearDrawable() override
Call gVirtualX->ClearWindow()
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 DrawPolyMarker()
Poly-marker.
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 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.
void SetAttText(const TAttText &att) override
Set 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
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