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/// Do nothing, sub-pads not cleared in GL
170
174
175////////////////////////////////////////////////////////////////////////////////
176/// Clear specified window - calling gVirtualX->ClearWindowW
177
179{
180 auto ctxt = gVirtualX->GetWindowContext(device);
181 if (ctxt)
182 gVirtualX->ClearWindowW(ctxt);
183}
184
185////////////////////////////////////////////////////////////////////////////////
186/// Returns true when cocoa backend is used
187
189{
190 return gVirtualX->InheritsFrom("TGCocoa");
191}
192
193////////////////////////////////////////////////////////////////////////////////
194///Not required at the moment.
195
196void TGLPadPainter::CopyDrawable(Int_t /* device */, Int_t /* px */, Int_t /* py */)
197{
198 // gVirtualX->CopyPixmapW(fWinContext, device, px, py);
199}
200
201////////////////////////////////////////////////////////////////////////////////
202///Not required at the moment.
203
205{
206 // gVirtualX->SelectWindow(device);
207 // gVirtualX->ClosePixmap();
208 fWinContext = 0;
209}
210
211////////////////////////////////////////////////////////////////////////////////
212///For gVirtualX this means select pixmap (or window)
213///and all subsequent drawings will go into
214///this pixmap. For OpenGL this means the change of
215///coordinate system and viewport.
216
218{
219 auto pad = dynamic_cast<TPad *>(gPad);
220 if (!fWinContext && pad)
221 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
222
223 if (fLocked)
224 return;
225
226 if (pad) {
227 // GL painter does not use proper id for sub-pads (see CreateDrawable)
228 // so one always use canvas ID to execute TVirtualX-specific commands
229 Int_t px = 0, py = 0;
230
231 pad->XYtoAbsPixel(pad->GetX1(), pad->GetY1(), px, py);
232
233 py = gPad->GetWh() - py;
234 //
237
238 glViewport(GLint(px * scale), GLint(py * scale),
239 GLsizei(gPad->GetWw() * pad->GetAbsWNDC() * scale),
240 GLsizei(gPad->GetWh() * pad->GetAbsHNDC() * scale));
241
244 glOrtho(pad->GetX1(), pad->GetX2(), pad->GetY1(), pad->GetY2(), -10., 10.);
245
248 glTranslated(0., 0., -1.);
249 } else {
250 ::Error("TGLPadPainter::SelectDrawable",
251 "function was called not from TPad or TCanvas code\n");
252 throw std::runtime_error("");
253 }
254}
255
256////////////////////////////////////////////////////////////////////////////////
257/// Call low-level update of selected drawable, redirect to gVirtualX.
258
260{
261 if (fWinContext)
262 gVirtualX->UpdateWindowW(fWinContext, mode);
263}
264
265
266////////////////////////////////////////////////////////////////////////////////
267/// Set drawing mode for specified device
268
270{
271 auto ctxt = fWinContext;
272 if (device)
273 ctxt = gVirtualX->GetWindowContext(device);
274 if (ctxt)
275 gVirtualX->SetDrawModeW(ctxt, (TVirtualX::EDrawMode) mode);
276}
277
278////////////////////////////////////////////////////////////////////////////////
279///Init gl-pad painter:
280///1. 2D painter does not use depth test, should not modify
281/// depth-buffer content (except initial cleanup).
282///2. Disable cull face.
283///3. Disable lighting.
284///4. Set viewport (to the whole canvas area).
285///5. Set camera.
286///6. Unlock painter.
287
289{
290 static bool gl_init = false;
291 if (!gl_init) {
293 if (version == 0)
294 Warning("TGLPadPainter::InitPainter", "GL initalization failed.");
295 else if (gDebug > 0)
296 Info("TGLPadPainter::InitPainter", "GL initalization successful.");
297 gl_init = true;
298 }
302
303 //Clear the buffer
304 glViewport(0, 0, GLsizei(gPad->GetWw()), GLsizei(gPad->GetWh()));
305
307 glClearColor(1.,1.,1.,1.);
310
313
314 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
315
318 glTranslated(0., 0., -1.);
319
320 fLocked = kFALSE;
321}
322
323////////////////////////////////////////////////////////////////////////////////
324///When TPad::Range for gPad is called, projection
325///must be changed in OpenGL.
326
328{
329 if (fLocked) return;
330
333
334 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
335
337}
338
339////////////////////////////////////////////////////////////////////////////////
340///Locked state of painter means, that
341///GL context can be invalid, so no GL calls
342///can be executed.
343
345{
346 if (fLocked) return;
347
348 glFinish();
349 fLocked = kTRUE;
350}
351
352/*
3532D primitives.
354*/
355
357
358////////////////////////////////////////////////////////////////////////////////
359///Draw line segment.
360
362{
363 if (fLocked) {
364 //GL pad painter can be called in non-standard situation:
365 //not from TPad::Paint, but
366 //from TView3D::ExecuteRotateView. This means in fact,
367 //that TView3D wants to draw itself in a XOR mode, via
368 //gVirtualX.
369 // TODO: only here set line attributes to virtual x
370 if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) {
371 gVirtualX->DrawLineW(fWinContext,
372 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
373 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2));
374 }
375
376 return;
377 }
378
380
381 glBegin(GL_LINES);
382 glVertex2d(x1, y1);
383 glVertex2d(x2, y2);
384 glEnd();
385
387 Double_t pointSize = GetAttLine().GetLineWidth();
393 glBegin(GL_POINTS);
394
395 glVertex2d(x1, y1);
396 glVertex2d(x2, y2);
397
398 glEnd();
399 glPointSize(1.f);
400 }
401
402}
403
404////////////////////////////////////////////////////////////////////////////////
405///Draw line segment in NDC coordinates.
406
408{
409 if (fLocked) {
410 // this code used when crosshair cursor is drawn
411 if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) {
412 // TODO: only here set line attributes to virtual x
413 gVirtualX->DrawLineW(fWinContext,
414 gPad->UtoAbsPixel(u1), gPad->VtoAbsPixel(v1),
415 gPad->UtoAbsPixel(u2), gPad->VtoAbsPixel(v2));
416 }
417 return;
418 }
419
421 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
422 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
423
424 glBegin(GL_LINES);
425 glVertex2d(gPad->GetX1() + u1 * xRange, gPad->GetY1() + v1 * yRange);
426 glVertex2d(gPad->GetX1() + u2 * xRange, gPad->GetY1() + v2 * yRange);
427 glEnd();
428}
429
430////////////////////////////////////////////////////////////////////////////////
431///Draw filled or hollow box.
432
434{
435 if (fLocked) {
436 //GL pad painter can be called in non-standard situation:
437 //not from TPad::Paint, but
438 //from TView3D::ExecuteRotateView. This means in fact,
439 //that TView3D wants to draw itself in a XOR mode, via
440 //gVirtualX.
441 // TODO: only here set line attributes to virtual x
442 if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) {
443 gVirtualX->DrawBoxW(fWinContext,
444 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
445 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2),
447 }
448 return;
449 }
450
452 Double_t xs[] = {x1, x2, x2, x1};
453 Double_t ys[] = {y1, y1, y2, y2};
455 return;
456 }
457
458 if (mode == kHollow) {
460 glBegin(GL_LINE_LOOP);
461 glVertex2d(x1, y1);
462 glVertex2d(x2, y1);
463 glVertex2d(x2, y2);
464 glVertex2d(x1, y2);
465 glEnd();
466 } else {
467 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE, &fGlFillAtt);//Set filling parameters.
468 glRectd(x1, y1, x2, y2);
469 }
470}
471
472////////////////////////////////////////////////////////////////////////////////
473///Draw tesselated polygon (probably, outline only).
474
476{
477 assert(x != nullptr && "DrawFillArea, parameter 'x' is null");
478 assert(y != nullptr && "DrawFillArea, parameter 'y' is null");
479
480 if (fLocked)
481 return;
482
483 if (n < 3) {
484 ::Error("TGLPadPainter::DrawFillArea",
485 "invalid number of points in a polygon");
486 return;
487 }
488
490 return DrawPolygonWithGradient(n, x, y);
491
492 if (fFullyTransparent) {
494 return DrawPolyLine(n, x, y);
495 }
496
498 DrawTesselation(n, x, y);
499}
500
501////////////////////////////////////////////////////////////////////////////////
502///Draw tesselated polygon (never called, probably, since TPad::PaintFillArea for floats
503///is deprecated).
504
506{
507 if (fLocked) return;
508
509 if (fFullyTransparent) {
511 return DrawPolyLine(n, x, y);
512 }
513
514 fVs.resize(n * 3);
515
516 for (Int_t i = 0; i < n; ++i) {
517 fVs[i * 3] = x[i];
518 fVs[i * 3 + 1] = y[i];
519 }
520
522
526
527 for (Int_t i = 0; i < n; ++i)
528 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
529
530
531 gluEndPolygon(t);
532}
533
534////////////////////////////////////////////////////////////////////////////////
535///Draw poly-line in user coordinates.
536
538{
539 if (fLocked) return;
540
542
543 glBegin(GL_LINE_STRIP);
544
545 for (Int_t i = 0; i < n; ++i)
546 glVertex2d(x[i], y[i]);
547
548 if (fIsHollowArea) {
549 glVertex2d(x[0], y[0]);
551 }
552 glEnd();
553
555 Double_t pointSize = GetAttLine().GetLineWidth();
561 glBegin(GL_POINTS);
562
563 for (Int_t i = 0; i < n; ++i)
564 glVertex2d(x[i], y[i]);
565
566 glEnd();
567 glPointSize(1.f);
568 }
569}
570
571////////////////////////////////////////////////////////////////////////////////
572///Never called?
573
575{
576 if (fLocked) return;
577
579
580 glBegin(GL_LINE_STRIP);
581
582 for (Int_t i = 0; i < n; ++i)
583 glVertex2f(x[i], y[i]);
584
585 if (fIsHollowArea) {
586 glVertex2f(x[0], y[0]);
588 }
589
590 glEnd();
591}
592
593////////////////////////////////////////////////////////////////////////////////
594///Poly line in NDC.
595
597{
598 if (fLocked) return;
599
601 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
602 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
603 const Double_t x1 = gPad->GetX1(), y1 = gPad->GetY1();
604
605 glBegin(GL_LINE_STRIP);
606
607 for (Int_t i = 0; i < n; ++i)
608 glVertex2d(x1 + u[i] * xRange, y1 + v[i] * yRange);
609
610 glEnd();
611}
612
613namespace {
614
615//Aux. function.
616template<class ValueType>
617void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst);
618
619}
620
621////////////////////////////////////////////////////////////////////////////////
622///Poly-marker.
623
625{
626 if (fLocked) return;
627
630}
631
632////////////////////////////////////////////////////////////////////////////////
633///Poly-marker.
634
636{
637 if (fLocked) return;
638
641}
642
643////////////////////////////////////////////////////////////////////////////////
644///Poly-marker.
645
647{
648 if (fLocked) return;
649
652 //
653 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
654 //
656 //
658
659 Float_t rgba[4] = {};
663
664
667
668 fMarker.SetMarkerSizeWidth(GetAttMarker().GetMarkerSize(), w);
669
670 const TPoint *xy = &fPoly[0];
672 const UInt_t n = UInt_t(fPoly.size());
673 switch (markerStyle) {
674 case kDot:
676 break;
677 case kPlus:
679 break;
680 case kStar:
681 case 31:
683 break;
684 case kCircle:
685 case kOpenCircle:
687 break;
688 case kMultiply:
689 fMarker.DrawX(n, xy);
690 break;
691 case kFullDotSmall://"Full dot small"
693 break;
694 case kFullDotMedium:
696 break;
697 case kFullDotLarge:
698 case kFullCircle:
700 break;
701 case kFullSquare:
703 break;
704 case kFullTriangleUp:
706 break;
709 break;
710 case kOpenSquare:
714 break;
715 case kOpenTriangleUp:
719 break;
720 case kOpenDiamond:
722 break;
723 case kOpenCross:
725 break;
726 case kFullStar:
728 break;
729 case kOpenStar:
731 break;
734 break;
735 case kFullDiamond:
737 break;
738 case kFullCross:
740 break;
743 break;
746 break;
749 break;
750 case kOctagonCross:
752 break;
755 break;
758 break;
761 break;
764 break;
767 break;
770 break;
773 break;
774 case kOpenCrossX:
776 break;
777 case kFullCrossX:
779 break;
780 case kFourSquaresX:
782 break;
783 case kFourSquaresPlus:
785 break;
786 }
787
790 glLineWidth(1.f);
791}
792
793////////////////////////////////////////////////////////////////////////////////
794
795template<class Char>
797{
799
801 //
802 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
803 //
805
806 Float_t rgba[4] = {};
809
810 //10 is the first valid font index.
811 //20 is FreeSerifBold, as in TTF.cxx and in TGLFontManager.cxx.
812 //shift - is the shift to access "extended" fonts.
814
816 if (fontIndex / 10 + shift > TGLFontManager::GetFontFileArray()->GetEntries())
817 fontIndex = 20 + shift * 10;
818 else
819 fontIndex += shift * 10;
820
822
823 fFM.RegisterFont(TMath::Max(Int_t(GetAttText().GetTextSize()) - 1, 10),//kTexture does not work if size < 10.
826 fF.PreRender();
827
828 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
829 fF.Render(text, gPad->XtoPixel(x), padH - gPad->YtoPixel(y), GetTextAngle(), GetTextMagnitude());
830
831 fF.PostRender();
833
835}
836
837////////////////////////////////////////////////////////////////////////////////
838///Draw text. This operation is especially
839///dangerous if in locked state -
840///ftgl will assert on zero texture size
841///(which is result of bad GL context).
842
844{
845 if (fLocked) return;
846
847 if (!GetAttText().GetTextSize())
848 return;
849
851}
852
853////////////////////////////////////////////////////////////////////////////////
854///Draw text. This operation is especially
855///dangerous if in locked state -
856///ftgl will assert on zero texture size
857///(which is result of bad GL context).
858
860{
861 if (fLocked) return;
862
863 if (!GetAttText().GetTextSize())
864 return;
865
867}
868
869////////////////////////////////////////////////////////////////////////////////
870///Draw text in NDC. This operation is especially
871///dangerous if in locked state -
872///ftgl will assert on zero texture size
873///(which is result of bad GL context).
874
876{
877 if (fLocked) return;
878
879 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
880 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
881 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
882}
883
884////////////////////////////////////////////////////////////////////////////////
885///Draw text in NDC. This operation is especially
886///dangerous if in locked state -
887///ftgl will assert on zero texture size
888///(which is result of bad GL context).
889
891{
892 if (fLocked) return;
893
894 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
895 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
896 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
897}
898
899////////////////////////////////////////////////////////////////////////////////
900///Save the projection matrix.
901///Attention! GL_PROJECTION will become the current matrix
902///after this call!
903
909
910////////////////////////////////////////////////////////////////////////////////
911///Restore the projection matrix.
912///Attention! GL_PROJECTION will become the current matrix
913///after this call!
914
920
921////////////////////////////////////////////////////////////////////////////////
922///Save the modelview matrix.
923///Attention! GL_MODELVIEW will become the current matrix
924///after this call!
925
931
932////////////////////////////////////////////////////////////////////////////////
933///Restore the modelview matrix.
934///Attention! GL_MODELVIEW will become the current matrix
935///after this call!
936
942
943////////////////////////////////////////////////////////////////////////////////
944///Extract and save the current viewport.
945
950
951////////////////////////////////////////////////////////////////////////////////
952///Restore the saved viewport.
953
955{
956 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
957}
958
959////////////////////////////////////////////////////////////////////////////////
960/// Using TImage save frame-buffer contents as a picture.
961
962void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
963{
964 auto canvas = pad->GetCanvas();
965 if (!canvas)
966 return;
967
968 canvas->Flush();
969
970 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
973 //In case GL_BGRA is not in gl.h (old windows' gl) - comment/uncomment lines.
974 //glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_BGRA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
975 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
976
977 std::unique_ptr<TImage> image(TImage::Create());
978 if (!image.get()) {
979 ::Error("TGLPadPainter::SaveImage", "TImage creation failed");
980 return;
981 }
982
983 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
984 UInt_t *argb = image->GetArgbArray();
985
986 if (!argb) {
987 ::Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
988 return;
989 }
990
991 const Int_t nLines = canvas->GetWh();
992 const Int_t nPixels = canvas->GetWw();
993
994 for (Int_t i = 0; i < nLines; ++i) {
995 Int_t base = (nLines - 1 - i) * nPixels;
996 for (Int_t j = 0; j < nPixels; ++j, ++base) {
997 //Uncomment/comment if you don't have GL_BGRA.
998
999 const UInt_t pix = buff[base];
1000 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
1001 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
1002
1003 //argb[i * nPixels + j] = buff[base];
1004 argb[i * nPixels + j] = bgra;
1005 }
1006 }
1007
1008 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
1009}
1010
1011////////////////////////////////////////////////////////////////////////////////
1012
1015{
1016 if (fLocked)
1017 return;
1018
1019 if (!pixelData) {
1020 //I'd prefer an assert.
1021 ::Error("TGLPadPainter::DrawPixels", "pixel data is null");
1022 return;
1023 }
1024
1025 if (std::numeric_limits<UInt_t>::digits >= 32) {
1026 //TASImage uses bit 31 as ...
1027 //alpha channel flag! FUUUUUUUUUUUUU ..... !!!
1028 CLRBIT(width, 31);
1029 CLRBIT(height, 31);
1030 }
1031
1032 if (!width) {
1033 //Assert is better.
1034 ::Error("TGLPadPainter::DrawPixels", "invalid width");
1035 return;
1036 }
1037
1038 if (!height) {
1039 //Assert is better.
1040 ::Error("TGLPadPainter::DrawPixels", "invalid height");
1041 return;
1042 }
1043
1044 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
1045 //TASImage passes pixel coordinates in pad's pixmap coordinate space.
1046 //While glRasterPosX said to work with 'window' coordinates,
1047 //that's a lie :) it does not :)
1048
1049 const Double_t rasterX = Double_t(dstX) / (pad->GetAbsWNDC() * pad->GetWw()) *
1050 (pad->GetX2() - pad->GetX1()) + pad->GetX1();
1051
1052 const Double_t yRange = pad->GetY2() - pad->GetY1();
1053 const Double_t rasterY = yRange - Double_t(dstY + height) / (pad->GetAbsHNDC() * pad->GetWh()) * yRange +
1054 pad->GetY1();
1055
1056 GLdouble oldPos[4] = {};
1057 //Save the previous raster pos.
1059
1061 //Stupid asimage provides us upside-down image.
1062 std::vector<unsigned char> upsideDownImage(4 * width * height);
1063 const unsigned char *srcLine = pixelData + 4 * width * (height - 1);
1064 unsigned char *dstLine = &upsideDownImage[0];
1065 for (UInt_t i = 0; i < height; ++i, srcLine -= 4 * width, dstLine += 4 * width)
1066 std::copy(srcLine, srcLine + 4 * width, dstLine);
1067
1068 if (enableBlending) {
1071 }
1072
1074
1075 if (enableBlending)
1077
1078 //Restore raster pos.
1079 glRasterPos2d(oldPos[0], oldPos[1]);
1080 } else
1081 ::Error("TGLPadPainter::DrawPixels", "no pad found to draw");
1082}
1083
1084//Aux. functions - gradient and solid fill of arbitrary area.
1085
1086////////////////////////////////////////////////////////////////////////////////
1087///At the moment I assume both linear and radial gradients will work the same way -
1088///using a stencil buffer and some big rectangle(s) to fill with a gradient.
1089///Thus I have a 'common' part - the part responsible for a stencil test.
1090
1092{
1093 assert(n > 2 && "DrawPolygonWithGradient, invalid number of points");
1094 assert(x != nullptr && "DrawPolygonWithGradient, parameter 'x' is null");
1095 assert(y != nullptr && "DrawPolygonWithGradient, parameter 'y' is null");
1096
1097 auto grad = dynamic_cast<TColorGradient *>(gROOT->GetColor(fGlFillAtt.GetFillColor()));
1098 assert(grad != nullptr && "DrawPolygonWithGradient, the current fill color is not a gradient fill");
1099
1100 if (fLocked)
1101 return;
1102
1103 //Now, some magic!
1105
1106 //TODO: check that the state is restored back correctly after
1107 // we done with a gradient.
1108 //TODO: make sure that we have glDepthMask set to false in general!
1110
1111 glStencilFunc(GL_NEVER, 1, 0xFF);
1112 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);// draw 1s on test fail (always)
1113 //Draw stencil pattern
1114 glStencilMask(0xFF);
1116
1117 //Draw our polygon into the stencil buffer:
1118 DrawTesselation(n, x, y);
1119
1121 glStencilMask(0x00);
1122 //Draw where stencil's value is 0
1123 glStencilFunc(GL_EQUAL, 0, 0xFF);
1124 //Draw only where stencil's value is 1
1125 glStencilFunc(GL_EQUAL, 1, 0xFF);
1126
1127 //At the moment radial gradient is derived from linear - it was convenient
1128 //at some point, but in fact it was a bad idea. And now I have to
1129 //first check radial gradient.
1130 //TODO: TRadialGradient must inherit TColorGradient directly.
1131 const TRadialGradient * const rGrad = dynamic_cast<const TRadialGradient *>(grad);
1132 if (rGrad)
1133 DrawGradient(rGrad, n, x, y);
1134 else {
1135 const TLinearGradient * const lGrad = dynamic_cast<const TLinearGradient *>(grad);
1136 assert(lGrad != nullptr && "DrawPolygonWithGradient, unknown gradient type");
1137 DrawGradient(lGrad, n, x, y);
1138 }
1139}
1140
1141////////////////////////////////////////////////////////////////////////////////
1142
1144 const Double_t *xs, const Double_t *ys)
1145{
1146 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1147 assert(nPoints > 2 && "DrawGradient, invalid number of points");
1148 assert(xs != nullptr && "DrawGradient, parameter 'xs' is null");
1149 assert(ys != nullptr && "DrawGradient, parameter 'ys' is null");
1150
1152 ::Warning("TGLPadPainter::DrawGradient",
1153 "extended radial gradient is not supported");//yet?
1154 return;
1155 }
1156
1157 //TODO: check the polygon's bbox!
1158 const auto &bbox = Rgl::Pad::FindBoundingRect(nPoints, xs, ys);
1159 //
1160 auto center = grad->GetCenter();
1161 auto radius = grad->GetRadius();
1162 //Adjust the center and radius depending on coordinate mode.
1164 radius *= TMath::Max(bbox.fWidth, bbox.fHeight);
1165 center.fX = bbox.fWidth * center.fX + bbox.fXMin;
1166 center.fY = bbox.fHeight * center.fY + bbox.fYMin;
1167 } else {
1168 const auto w = gPad->GetX2() - gPad->GetX1();
1169 const auto h = gPad->GetY2() - gPad->GetY1();
1170
1171 radius *= TMath::Max(w, h);
1172 center.fX *= w;
1173 center.fY *= h;
1174 }
1175 //Now for the gradient fill we switch into pixel coordinates:
1176 const auto pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1177 const auto pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1178 //
1181 //A new ortho projection:
1184 //
1185 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1186 //
1188 center.fX = gPad->XtoPixel(center.fX);
1189 center.fY = pixelH - gPad->YtoPixel(center.fY);
1190
1191 Double_t maxR = 0.;
1192 {
1193 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1194 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1195 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1196 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1197 //Get the longest distance from the center to the bounding box vertices
1198 //(this will be the maximum possible radius):
1199 const Double_t maxDistX = TMath::Max(TMath::Abs(center.fX - xMin),
1200 TMath::Abs(center.fX - xMax));
1201 const Double_t maxDistY = TMath::Max(TMath::Abs(center.fY - yMin),
1202 TMath::Abs(center.fY - yMax));
1204 }
1205
1206 //If gradient 'stops inside the polygon', we use
1207 //the solid fill for the area outside of radial gradient:
1208 const Bool_t solidFillAfter = maxR > radius;
1209 //We emulate a radial gradient using triangles and linear gradient:
1210 //TODO: Can be something smarter? (btw even 100 seems to be enough)
1211 const UInt_t nSlices = 500;
1212
1213 const auto nColors = grad->GetNumberOfSteps();
1214 //+1 - the strip from the last color's position to radius,
1215 //and (probably) + 1 for solidFillAfter.
1216 const auto nCircles = nColors + 1 + solidFillAfter;
1217
1218 //TODO: can locations be outside of [0., 1.] ???
1219 //at the moment I assume the answer is NO, NEVER.
1220 const auto locations = grad->GetColorPositions();
1221 // * 2 below == x,y
1222 std::vector<Double_t> circles(nSlices * nCircles * 2);
1223 const Double_t angle = TMath::TwoPi() / nSlices;
1224
1225 //"Main" circles (for colors at locations[i]).
1226 for (UInt_t i = 0; i < nColors; ++i) {
1227 const auto circle = &circles[i * nSlices * 2];
1228 //TODO: either check locations here or somewhere else.
1229 const auto r = radius * locations[i];
1230 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1231 circle[j] = center.fX + r * TMath::Cos(angle * j);
1232 circle[j + 1] = center.fY + r * TMath::Sin(angle * j);
1233 }
1234 //The "closing" vertices:
1235 circle[(nSlices - 1) * 2] = circle[0];
1236 circle[(nSlices - 1) * 2 + 1] = circle[1];
1237 }
1238
1239 {
1240 //The strip between lastPos and radius:
1241 const auto circle = &circles[nColors * nSlices * 2];
1242 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1243 circle[j] = center.fX + radius * TMath::Cos(angle * j);
1244 circle[j + 1] = center.fY + radius * TMath::Sin(angle * j);
1245 }
1246
1247 circle[(nSlices - 1) * 2] = circle[0];
1248 circle[(nSlices - 1) * 2 + 1] = circle[1];
1249 }
1250
1251 if (solidFillAfter) {
1252 //The strip after the radius:
1253 const auto circle = &circles[(nCircles - 1) * nSlices * 2];
1254 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1255 circle[j] = center.fX + maxR * TMath::Cos(angle * j);
1256 circle[j + 1] = center.fY + maxR * TMath::Sin(angle * j);
1257 }
1258
1259 circle[(nSlices - 1) * 2] = circle[0];
1260 circle[(nSlices - 1) * 2 + 1] = circle[1];
1261 }
1262
1263 //Now we draw:
1264 //1) triangle fan in the center (from center to the locations[1],
1265 // with a solid fill).
1266 //2) quad strips for colors.
1267 //3) additional quad strip from the lastLocation to the radius
1268 //4) additional quad strip (if any) from the radius to maxR.
1269
1270 //RGBA values:
1271 const auto rgba = grad->GetColors();
1272
1274 //TODO?
1276
1277 //Probably a degenerated case. Maybe not.
1280 glVertex2d(center.fX, center.fY);
1281
1282 for (UInt_t i = 0, e = nSlices * 2; i < e; i += 2)
1283 glVertex2dv(&circles[i]);
1284
1285 glEnd();
1286
1287 //No auto for circles, explicit types to have const Double_t * const, not Duble_t * const.
1288 for (UInt_t i = 0; i < nColors - 1; ++i) {
1289 const Double_t * const inner = &circles[i * nSlices * 2];
1290 const auto innerRGBA = rgba + i * 4;
1291 const auto outerRGBA = rgba + (i + 1) * 4;
1292 const Double_t * const outer = &circles[(i + 1) * nSlices * 2];
1293
1295 }
1296
1297 //Probably degenerated strip.
1298 {
1299 const Double_t * const inner = &circles[nSlices * (nColors - 1) * 2];
1300 const auto solidRGBA = rgba + (nColors - 1) * 4;
1301 const Double_t * const outer = &circles[nSlices * nColors * 2];
1302
1304 }
1305
1306 if (solidFillAfter) {
1307 const Double_t * const inner = &circles[nSlices * nColors * 2];
1308 const auto solidRGBA = rgba + (nColors - 1) * 4;
1309 const Double_t * const outer = &circles[nSlices * (nColors + 1) * 2];
1310
1312 }
1313
1316}
1317
1318////////////////////////////////////////////////////////////////////////////////
1319
1321 const Double_t *x, const Double_t *y)
1322{
1323 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1324 assert(n > 2 && "DrawGradient, invalid number of points");
1325 assert(x != nullptr && "DrawGradient, parameter 'x' is null");
1326 assert(y != nullptr && "DrawGradient, parameter 'y' is null");
1327
1328 //Now we fill the whole scene with one big rectangle
1329 //(group of rectangles) with a gradient fill using
1330 //stencil test.
1331
1332 //Find a bounding rect.
1333 const auto &bbox = Rgl::Pad::FindBoundingRect(n, x, y);
1334 //TODO: check the bbox??
1335
1336 //For the gradient fill we switch into the
1337 //pixel coordinates.
1340
1341 //A new ortho projection:
1344
1345 const Double_t pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1346 const Double_t pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1347 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1348
1349 //A new modelview:
1352 //
1353 TColorGradient::Point start = grad->GetStart();
1354 TColorGradient::Point end = grad->GetEnd();
1355
1356 //Change gradient coordinates from 'NDC' to pad coords:
1358 {
1359 const Double_t w = gPad->GetX2() - gPad->GetX1();
1360 const Double_t h = gPad->GetY2() - gPad->GetY1();
1361
1362 start.fX = start.fX * w;
1363 start.fY = start.fY * h;
1364 end.fX = end.fX * w;
1365 end.fY = end.fY * h;
1366 } else {
1367 start.fX = start.fX * bbox.fWidth + bbox.fXMin;
1368 start.fY = start.fY * bbox.fHeight + bbox.fYMin;
1369 end.fX = end.fX * bbox.fWidth + bbox.fXMin;
1370 end.fY = end.fY * bbox.fHeight + bbox.fYMin;
1371 }
1372
1373 //TODO: with a radial fill we'll have to extract the code
1374 // below into the separate function/and have additional function
1375 // for a radial gradient.
1376 //Now from pad to pixels:
1377 start.fX = gPad->XtoPixel(start.fX);
1378 start.fY = pixelH - gPad->YtoPixel(start.fY);
1379 end.fX = gPad->XtoPixel(end.fX);
1380 end.fY = pixelH - gPad->YtoPixel(end.fY);
1381 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1382 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1383 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1384 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1385 //
1386
1387 //TODO: check all calculations!
1388
1389 //Get the longest distance from the start point to the bounding box vertices:
1390 const Double_t maxDistX = TMath::Max(TMath::Abs(start.fX - xMin), TMath::Abs(start.fX - xMax));
1391 const Double_t maxDistY = TMath::Max(TMath::Abs(start.fY - yMin), TMath::Abs(start.fY - yMax));
1392
1393 const Double_t startEndLength = TMath::Sqrt((end.fX - start.fX) * (end.fX - start.fX) +
1394 (end.fY - start.fY) * (end.fY - start.fY));
1397
1398 //Boxes with a gradients to emulate gradient fill with many colors:
1399 const Double_t * const colorPositions = grad->GetColorPositions();
1400 std::vector<Double_t> gradBoxes(grad->GetNumberOfSteps() + 2);
1401 gradBoxes[0] = start.fY - h;
1402 for (unsigned i = 1; i <= grad->GetNumberOfSteps(); ++i)
1403 gradBoxes[i] = startEndLength * colorPositions[i - 1] + start.fY;
1404
1405 gradBoxes[grad->GetNumberOfSteps() + 1] = start.fY + h;
1406
1407 //Rotation angle - gradient's axis:
1408 Double_t angle = TMath::ACos((startEndLength * (end.fY - start.fY)) /
1410 if (end.fX > start.fX)
1411 angle *= -1;
1412
1413 glTranslated(start.fX, start.fY, 0.);
1414 glRotated(angle, 0., 0., 1.);
1415 glTranslated(-start.fX, -start.fY, 0.);
1416 //
1417 const Double_t * const rgba = grad->GetColors();
1418
1419 const unsigned nEdges = gradBoxes.size();
1420 const unsigned nColors = grad->GetNumberOfSteps();
1421 const Double_t xLeft = start.fX - h, xRight = start.fX + h;
1422
1424 //TODO?
1426
1429 rgba + (nColors - 1) * 4, rgba + (nColors - 1) * 4);
1430
1431 for (unsigned i = 1; i < nEdges - 2; ++i)
1433 xRight, rgba + (i - 1) * 4, rgba + i * 4);
1434
1437}
1438
1439////////////////////////////////////////////////////////////////////////////////
1440
1442{
1443 assert(n > 2 && "DrawTesselation, invalid number of points");
1444 assert(x != nullptr && "DrawTesselation, parameter 'x' is null");
1445 assert(y != nullptr && "DrawTesselation, parameter 'y' is null");
1446
1447 //Data for a tesselator:
1448 fVs.resize(n * 3);
1449
1450 for (Int_t i = 0; i < n; ++i) {
1451 fVs[i * 3] = x[i];
1452 fVs[i * 3 + 1] = y[i];
1453 fVs[i * 3 + 2] = 0.;
1454 }
1455
1456 //TODO: A very primitive way to tesselate - check what
1457 //kind of polygons we can really have from TPad/TCanvas.
1459 gluBeginPolygon(t);
1461
1462 for (Int_t i = 0; i < n; ++i)
1463 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
1464
1465 gluEndPolygon(t);
1466}
1467
1468
1469//Aux. functions.
1470namespace {
1471
1472template<class ValueType>
1473void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst)
1474{
1475 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
1476
1477 dst.resize(n);
1478 for (Int_t i = 0; i < n; ++i) {
1479 dst[i].fX = gPad->XtoPixel(x[i]);
1480 dst[i].fY = padH - gPad->YtoPixel(y[i]);
1481 }
1482}
1483
1484}
1485
#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
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:367
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
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 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