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
76
77////////////////////////////////////////////////////////////////////////////////
78///Delegate to gVirtualX.
79
81{
82 return gVirtualX->GetTextMagnitude();
83}
84
85////////////////////////////////////////////////////////////////////////////////
86/// Select pad where current painting will be performed
87
89{
90 // GL painter does not use proper id for sub-pads (see CreateDrawable)
91 // so one always use canvas ID to execute TVirtualX-specific commands
92 if (!fWinContext)
93 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
94}
95
96////////////////////////////////////////////////////////////////////////////////
97/// Set fill attributes
98
100{
102
103 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
104 if (fWinContext && gVirtualX)
105 gVirtualX->SetAttFill(fWinContext, att);
106}
107
108////////////////////////////////////////////////////////////////////////////////
109/// Set line attributes
110
112{
114
115 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
116 if (fWinContext && gVirtualX)
117 gVirtualX->SetAttLine(fWinContext, att);
118}
119
120////////////////////////////////////////////////////////////////////////////////
121/// Set marker attributes
122
124{
126
127 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
128 if (fWinContext && gVirtualX)
129 gVirtualX->SetAttMarker(fWinContext, att);
130}
131
132////////////////////////////////////////////////////////////////////////////////
133/// Set text attributes
134
136{
138
139 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
140 if (fWinContext && gVirtualX)
141 gVirtualX->SetAttText(fWinContext, att);
142}
143
144/*
145"Pixmap" part of TGLPadPainter.
146*/
147
148////////////////////////////////////////////////////////////////////////////////
149///Not required at the moment.
150
152{
153 // return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
154 return 0;
155}
156
157////////////////////////////////////////////////////////////////////////////////
158/// Resize a gVirtualX Pixmap.
159
161{
162 return gVirtualX->ResizePixmap(device, w, h);
163}
164
165////////////////////////////////////////////////////////////////////////////////
166/// Call gVirtualX->ClearWindow()
167
169{
170 gVirtualX->ClearWindow();
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Returns true when cocoa backend is used
175
177{
178 return gVirtualX->InheritsFrom("TGCocoa");
179}
180
181////////////////////////////////////////////////////////////////////////////////
182///Not required at the moment.
183
184void TGLPadPainter::CopyDrawable(Int_t /* device */, Int_t /* px */, Int_t /* py */)
185{
186 // gVirtualX->CopyPixmap(device, px, py);
187}
188
189////////////////////////////////////////////////////////////////////////////////
190///Not required at the moment.
191
193{
194 // gVirtualX->SelectWindow(device);
195 // gVirtualX->ClosePixmap();
196 fWinContext = 0;
197}
198
199////////////////////////////////////////////////////////////////////////////////
200///For gVirtualX this means select pixmap (or window)
201///and all subsequent drawings will go into
202///this pixmap. For OpenGL this means the change of
203///coordinate system and viewport.
204
206{
207 auto pad = dynamic_cast<TPad *>(gPad);
208 if (!fWinContext && pad)
209 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
210
211 if (fLocked)
212 return;
213
214 if (pad) {
215 // GL painter does not use proper id for sub-pads (see CreateDrawable)
216 // so one always use canvas ID to execute TVirtualX-specific commands
217 Int_t px = 0, py = 0;
218
219 pad->XYtoAbsPixel(pad->GetX1(), pad->GetY1(), px, py);
220
221 py = gPad->GetWh() - py;
222 //
225
226 glViewport(GLint(px * scale), GLint(py * scale),
227 GLsizei(gPad->GetWw() * pad->GetAbsWNDC() * scale),
228 GLsizei(gPad->GetWh() * pad->GetAbsHNDC() * scale));
229
232 glOrtho(pad->GetX1(), pad->GetX2(), pad->GetY1(), pad->GetY2(), -10., 10.);
233
236 glTranslated(0., 0., -1.);
237 } else {
238 ::Error("TGLPadPainter::SelectDrawable",
239 "function was called not from TPad or TCanvas code\n");
240 throw std::runtime_error("");
241 }
242}
243
244////////////////////////////////////////////////////////////////////////////////
245/// Call low-level update of selected drawable, redirect to gVirtualX.
246
248{
249 if (fWinContext)
250 gVirtualX->UpdateWindowW(fWinContext, mode);
251}
252
253
254////////////////////////////////////////////////////////////////////////////////
255/// Set drawing mode for specified device
256
258{
259 auto ctxt = fWinContext;
260 if (device)
261 ctxt = gVirtualX->GetWindowContext(device);
262 if (ctxt)
263 gVirtualX->SetDrawModeW(ctxt, (TVirtualX::EDrawMode) mode);
264}
265
266////////////////////////////////////////////////////////////////////////////////
267///Init gl-pad painter:
268///1. 2D painter does not use depth test, should not modify
269/// depth-buffer content (except initial cleanup).
270///2. Disable cull face.
271///3. Disable lighting.
272///4. Set viewport (to the whole canvas area).
273///5. Set camera.
274///6. Unlock painter.
275
277{
278 static bool gl_init = false;
279 if (!gl_init) {
281 if (version == 0)
282 Warning("TGLPadPainter::InitPainter", "GL initalization failed.");
283 else if (gDebug > 0)
284 Info("TGLPadPainter::InitPainter", "GL initalization successful.");
285 gl_init = true;
286 }
290
291 //Clear the buffer
292 glViewport(0, 0, GLsizei(gPad->GetWw()), GLsizei(gPad->GetWh()));
293
295 glClearColor(1.,1.,1.,1.);
298
301
302 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
303
306 glTranslated(0., 0., -1.);
307
308 fLocked = kFALSE;
309}
310
311////////////////////////////////////////////////////////////////////////////////
312///When TPad::Range for gPad is called, projection
313///must be changed in OpenGL.
314
316{
317 if (fLocked) return;
318
321
322 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
323
325}
326
327////////////////////////////////////////////////////////////////////////////////
328///Locked state of painter means, that
329///GL context can be invalid, so no GL calls
330///can be executed.
331
333{
334 if (fLocked) return;
335
336 glFinish();
337 fLocked = kTRUE;
338}
339
340/*
3412D primitives.
342*/
343
345
346////////////////////////////////////////////////////////////////////////////////
347///Draw line segment.
348
350{
351 if (fLocked) {
352 //GL pad painter can be called in non-standard situation:
353 //not from TPad::Paint, but
354 //from TView3D::ExecuteRotateView. This means in fact,
355 //that TView3D wants to draw itself in a XOR mode, via
356 //gVirtualX.
357 // TODO: only here set line attributes to virtual x
358 if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) {
359 gVirtualX->DrawLineW(fWinContext,
360 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
361 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2));
362 }
363
364 return;
365 }
366
368
369 glBegin(GL_LINES);
370 glVertex2d(x1, y1);
371 glVertex2d(x2, y2);
372 glEnd();
373
375 Double_t pointSize = GetAttLine().GetLineWidth();
381 glBegin(GL_POINTS);
382
383 glVertex2d(x1, y1);
384 glVertex2d(x2, y2);
385
386 glEnd();
387 glPointSize(1.f);
388 }
389
390}
391
392////////////////////////////////////////////////////////////////////////////////
393///Draw line segment in NDC coordinates.
394
396{
397 if (fLocked) {
398 // this code used when crosshair cursor is drawn
399 if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) {
400 const Int_t px1 = gPad->UtoPixel(u1);
401 const Int_t py1 = gPad->VtoPixel(v1);
402 const Int_t px2 = gPad->UtoPixel(u2);
403 const Int_t py2 = gPad->VtoPixel(v2);
404 // TODO: only here set line attributes to virtual x
405 gVirtualX->DrawLineW(fWinContext, px1, py1, px2, py2);
406 }
407 return;
408 }
409
411 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
412 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
413
414 glBegin(GL_LINES);
415 glVertex2d(gPad->GetX1() + u1 * xRange, gPad->GetY1() + v1 * yRange);
416 glVertex2d(gPad->GetX1() + u2 * xRange, gPad->GetY1() + v2 * yRange);
417 glEnd();
418}
419
420////////////////////////////////////////////////////////////////////////////////
421///Draw filled or hollow box.
422
424{
425 if (fLocked) return;
426
428 Double_t xs[] = {x1, x2, x2, x1};
429 Double_t ys[] = {y1, y1, y2, y2};
431 return;
432 }
433
434 if (mode == kHollow) {
436 //
438 glRectd(x1, y1, x2, y2);
440 glLineWidth(1.f);
441 } else {
442 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE, &GetAttFill());//Set filling parameters.
443 glRectd(x1, y1, x2, y2);
444 }
445}
446
447////////////////////////////////////////////////////////////////////////////////
448///Draw tesselated polygon (probably, outline only).
449
451{
452 assert(x != nullptr && "DrawFillArea, parameter 'x' is null");
453 assert(y != nullptr && "DrawFillArea, parameter 'y' is null");
454
455 if (fLocked)
456 return;
457
458 if (n < 3) {
459 ::Error("TGLPadPainter::DrawFillArea",
460 "invalid number of points in a polygon");
461 return;
462 }
463
465 return DrawPolygonWithGradient(n, x, y);
466
467 if (!GetAttFill().GetFillStyle()) {
469 return DrawPolyLine(n, x, y);
470 }
471
473 DrawTesselation(n, x, y);
474}
475
476////////////////////////////////////////////////////////////////////////////////
477///Draw tesselated polygon (never called, probably, since TPad::PaintFillArea for floats
478///is deprecated).
479
481{
482 if (fLocked) return;
483
484 if (!GetAttFill().GetFillStyle()) {
486 return DrawPolyLine(n, x, y);
487 }
488
489 fVs.resize(n * 3);
490
491 for (Int_t i = 0; i < n; ++i) {
492 fVs[i * 3] = x[i];
493 fVs[i * 3 + 1] = y[i];
494 }
495
497
501
502 for (Int_t i = 0; i < n; ++i)
503 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
504
505
506 gluEndPolygon(t);
507}
508
509////////////////////////////////////////////////////////////////////////////////
510///Draw poly-line in user coordinates.
511
513{
514 if (fLocked) return;
515
517
518 glBegin(GL_LINE_STRIP);
519
520 for (Int_t i = 0; i < n; ++i)
521 glVertex2d(x[i], y[i]);
522
523 if (fIsHollowArea) {
524 glVertex2d(x[0], y[0]);
526 }
527 glEnd();
528
530 Double_t pointSize = GetAttLine().GetLineWidth();
536 glBegin(GL_POINTS);
537
538 for (Int_t i = 0; i < n; ++i)
539 glVertex2d(x[i], y[i]);
540
541 glEnd();
542 glPointSize(1.f);
543 }
544}
545
546////////////////////////////////////////////////////////////////////////////////
547///Never called?
548
550{
551 if (fLocked) return;
552
554
555 glBegin(GL_LINE_STRIP);
556
557 for (Int_t i = 0; i < n; ++i)
558 glVertex2f(x[i], y[i]);
559
560 if (fIsHollowArea) {
561 glVertex2f(x[0], y[0]);
563 }
564
565 glEnd();
566}
567
568////////////////////////////////////////////////////////////////////////////////
569///Poly line in NDC.
570
572{
573 if (fLocked) return;
574
576 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
577 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
578 const Double_t x1 = gPad->GetX1(), y1 = gPad->GetY1();
579
580 glBegin(GL_LINE_STRIP);
581
582 for (Int_t i = 0; i < n; ++i)
583 glVertex2d(x1 + u[i] * xRange, y1 + v[i] * yRange);
584
585 glEnd();
586}
587
588namespace {
589
590//Aux. function.
591template<class ValueType>
592void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst);
593
594}
595
596////////////////////////////////////////////////////////////////////////////////
597///Poly-marker.
598
600{
601 if (fLocked) return;
602
605}
606
607////////////////////////////////////////////////////////////////////////////////
608///Poly-marker.
609
611{
612 if (fLocked) return;
613
616}
617
618////////////////////////////////////////////////////////////////////////////////
619///Poly-marker.
620
622{
623 if (fLocked) return;
624
627 //
628 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
629 //
631 //
633
634 Float_t rgba[4] = {};
638
639
642
643 fMarker.SetMarkerSizeWidth(GetAttMarker().GetMarkerSize(), w);
644
645 const TPoint *xy = &fPoly[0];
647 const UInt_t n = UInt_t(fPoly.size());
648 switch (markerStyle) {
649 case kDot:
651 break;
652 case kPlus:
654 break;
655 case kStar:
656 case 31:
658 break;
659 case kCircle:
660 case kOpenCircle:
662 break;
663 case kMultiply:
664 fMarker.DrawX(n, xy);
665 break;
666 case kFullDotSmall://"Full dot small"
668 break;
669 case kFullDotMedium:
671 break;
672 case kFullDotLarge:
673 case kFullCircle:
675 break;
676 case kFullSquare:
678 break;
679 case kFullTriangleUp:
681 break;
684 break;
685 case kOpenSquare:
689 break;
690 case kOpenTriangleUp:
694 break;
695 case kOpenDiamond:
697 break;
698 case kOpenCross:
700 break;
701 case kFullStar:
703 break;
704 case kOpenStar:
706 break;
709 break;
710 case kFullDiamond:
712 break;
713 case kFullCross:
715 break;
718 break;
721 break;
724 break;
725 case kOctagonCross:
727 break;
730 break;
733 break;
736 break;
739 break;
742 break;
745 break;
748 break;
749 case kOpenCrossX:
751 break;
752 case kFullCrossX:
754 break;
755 case kFourSquaresX:
757 break;
758 case kFourSquaresPlus:
760 break;
761 }
762
765 glLineWidth(1.f);
766}
767
768////////////////////////////////////////////////////////////////////////////////
769
770template<class Char>
772{
774
776 //
777 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
778 //
780
781 Float_t rgba[4] = {};
784
785 //10 is the first valid font index.
786 //20 is FreeSerifBold, as in TTF.cxx and in TGLFontManager.cxx.
787 //shift - is the shift to access "extended" fonts.
789
791 if (fontIndex / 10 + shift > TGLFontManager::GetFontFileArray()->GetEntries())
792 fontIndex = 20 + shift * 10;
793 else
794 fontIndex += shift * 10;
795
797
798 fFM.RegisterFont(TMath::Max(Int_t(GetAttText().GetTextSize()) - 1, 10),//kTexture does not work if size < 10.
801 fF.PreRender();
802
803 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
804 fF.Render(text, gPad->XtoPixel(x), padH - gPad->YtoPixel(y), GetTextAngle(), GetTextMagnitude());
805
806 fF.PostRender();
808
810}
811
812////////////////////////////////////////////////////////////////////////////////
813///Draw text. This operation is especially
814///dangerous if in locked state -
815///ftgl will assert on zero texture size
816///(which is result of bad GL context).
817
819{
820 if (fLocked) return;
821
822 if (!GetAttText().GetTextSize())
823 return;
824
826}
827
828////////////////////////////////////////////////////////////////////////////////
829///Draw text. This operation is especially
830///dangerous if in locked state -
831///ftgl will assert on zero texture size
832///(which is result of bad GL context).
833
835{
836 if (fLocked) return;
837
838 if (!GetAttText().GetTextSize())
839 return;
840
842}
843
844////////////////////////////////////////////////////////////////////////////////
845///Draw text in NDC. This operation is especially
846///dangerous if in locked state -
847///ftgl will assert on zero texture size
848///(which is result of bad GL context).
849
851{
852 if (fLocked) return;
853
854 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
855 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
856 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
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///Save the projection matrix.
876///Attention! GL_PROJECTION will become the current matrix
877///after this call!
878
884
885////////////////////////////////////////////////////////////////////////////////
886///Restore the projection matrix.
887///Attention! GL_PROJECTION will become the current matrix
888///after this call!
889
895
896////////////////////////////////////////////////////////////////////////////////
897///Save the modelview matrix.
898///Attention! GL_MODELVIEW will become the current matrix
899///after this call!
900
906
907////////////////////////////////////////////////////////////////////////////////
908///Restore the modelview matrix.
909///Attention! GL_MODELVIEW will become the current matrix
910///after this call!
911
917
918////////////////////////////////////////////////////////////////////////////////
919///Extract and save the current viewport.
920
925
926////////////////////////////////////////////////////////////////////////////////
927///Restore the saved viewport.
928
930{
931 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
932}
933
934////////////////////////////////////////////////////////////////////////////////
935/// Using TImage save frame-buffer contents as a picture.
936
937void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
938{
939 auto canvas = pad->GetCanvas();
940 if (!canvas)
941 return;
942
943 canvas->Flush();
944
945 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
948 //In case GL_BGRA is not in gl.h (old windows' gl) - comment/uncomment lines.
949 //glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_BGRA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
950 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
951
952 std::unique_ptr<TImage> image(TImage::Create());
953 if (!image.get()) {
954 ::Error("TGLPadPainter::SaveImage", "TImage creation failed");
955 return;
956 }
957
958 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
959 UInt_t *argb = image->GetArgbArray();
960
961 if (!argb) {
962 ::Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
963 return;
964 }
965
966 const Int_t nLines = canvas->GetWh();
967 const Int_t nPixels = canvas->GetWw();
968
969 for (Int_t i = 0; i < nLines; ++i) {
970 Int_t base = (nLines - 1 - i) * nPixels;
971 for (Int_t j = 0; j < nPixels; ++j, ++base) {
972 //Uncomment/comment if you don't have GL_BGRA.
973
974 const UInt_t pix = buff[base];
975 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
976 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
977
978 //argb[i * nPixels + j] = buff[base];
979 argb[i * nPixels + j] = bgra;
980 }
981 }
982
983 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
984}
985
986////////////////////////////////////////////////////////////////////////////////
987
990{
991 if (fLocked)
992 return;
993
994 if (!pixelData) {
995 //I'd prefer an assert.
996 ::Error("TGLPadPainter::DrawPixels", "pixel data is null");
997 return;
998 }
999
1000 if (std::numeric_limits<UInt_t>::digits >= 32) {
1001 //TASImage uses bit 31 as ...
1002 //alpha channel flag! FUUUUUUUUUUUUU ..... !!!
1003 CLRBIT(width, 31);
1004 CLRBIT(height, 31);
1005 }
1006
1007 if (!width) {
1008 //Assert is better.
1009 ::Error("TGLPadPainter::DrawPixels", "invalid width");
1010 return;
1011 }
1012
1013 if (!height) {
1014 //Assert is better.
1015 ::Error("TGLPadPainter::DrawPixels", "invalid height");
1016 return;
1017 }
1018
1019 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
1020 //TASImage passes pixel coordinates in pad's pixmap coordinate space.
1021 //While glRasterPosX said to work with 'window' coordinates,
1022 //that's a lie :) it does not :)
1023
1024 const Double_t rasterX = Double_t(dstX) / (pad->GetAbsWNDC() * pad->GetWw()) *
1025 (pad->GetX2() - pad->GetX1()) + pad->GetX1();
1026
1027 const Double_t yRange = pad->GetY2() - pad->GetY1();
1028 const Double_t rasterY = yRange - Double_t(dstY + height) / (pad->GetAbsHNDC() * pad->GetWh()) * yRange +
1029 pad->GetY1();
1030
1031 GLdouble oldPos[4] = {};
1032 //Save the previous raster pos.
1034
1036 //Stupid asimage provides us upside-down image.
1037 std::vector<unsigned char> upsideDownImage(4 * width * height);
1038 const unsigned char *srcLine = pixelData + 4 * width * (height - 1);
1039 unsigned char *dstLine = &upsideDownImage[0];
1040 for (UInt_t i = 0; i < height; ++i, srcLine -= 4 * width, dstLine += 4 * width)
1041 std::copy(srcLine, srcLine + 4 * width, dstLine);
1042
1043 if (enableBlending) {
1046 }
1047
1049
1050 if (enableBlending)
1052
1053 //Restore raster pos.
1054 glRasterPos2d(oldPos[0], oldPos[1]);
1055 } else
1056 ::Error("TGLPadPainter::DrawPixels", "no pad found to draw");
1057}
1058
1059//Aux. functions - gradient and solid fill of arbitrary area.
1060
1061////////////////////////////////////////////////////////////////////////////////
1062///At the moment I assume both linear and radial gradients will work the same way -
1063///using a stencil buffer and some big rectangle(s) to fill with a gradient.
1064///Thus I have a 'common' part - the part responsible for a stencil test.
1065
1067{
1068 assert(n > 2 && "DrawPolygonWithGradient, invalid number of points");
1069 assert(x != nullptr && "DrawPolygonWithGradient, parameter 'x' is null");
1070 assert(y != nullptr && "DrawPolygonWithGradient, parameter 'y' is null");
1071
1072 auto grad = dynamic_cast<TColorGradient *>(gROOT->GetColor(GetAttFill().GetFillColor()));
1073 assert(grad != nullptr && "DrawPolygonWithGradient, the current fill color is not a gradient fill");
1074
1075 if (fLocked)
1076 return;
1077
1078 //Now, some magic!
1080
1081 //TODO: check that the state is restored back correctly after
1082 // we done with a gradient.
1083 //TODO: make sure that we have glDepthMask set to false in general!
1085
1086 glStencilFunc(GL_NEVER, 1, 0xFF);
1087 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);// draw 1s on test fail (always)
1088 //Draw stencil pattern
1089 glStencilMask(0xFF);
1091
1092 //Draw our polygon into the stencil buffer:
1093 DrawTesselation(n, x, y);
1094
1096 glStencilMask(0x00);
1097 //Draw where stencil's value is 0
1098 glStencilFunc(GL_EQUAL, 0, 0xFF);
1099 //Draw only where stencil's value is 1
1100 glStencilFunc(GL_EQUAL, 1, 0xFF);
1101
1102 //At the moment radial gradient is derived from linear - it was convenient
1103 //at some point, but in fact it was a bad idea. And now I have to
1104 //first check radial gradient.
1105 //TODO: TRadialGradient must inherit TColorGradient directly.
1106 const TRadialGradient * const rGrad = dynamic_cast<const TRadialGradient *>(grad);
1107 if (rGrad)
1108 DrawGradient(rGrad, n, x, y);
1109 else {
1110 const TLinearGradient * const lGrad = dynamic_cast<const TLinearGradient *>(grad);
1111 assert(lGrad != nullptr && "DrawPolygonWithGradient, unknown gradient type");
1112 DrawGradient(lGrad, n, x, y);
1113 }
1114}
1115
1116////////////////////////////////////////////////////////////////////////////////
1117
1119 const Double_t *xs, const Double_t *ys)
1120{
1121 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1122 assert(nPoints > 2 && "DrawGradient, invalid number of points");
1123 assert(xs != nullptr && "DrawGradient, parameter 'xs' is null");
1124 assert(ys != nullptr && "DrawGradient, parameter 'ys' is null");
1125
1127 ::Warning("TGLPadPainter::DrawGradient",
1128 "extended radial gradient is not supported");//yet?
1129 return;
1130 }
1131
1132 //TODO: check the polygon's bbox!
1133 const auto &bbox = Rgl::Pad::FindBoundingRect(nPoints, xs, ys);
1134 //
1135 auto center = grad->GetCenter();
1136 auto radius = grad->GetRadius();
1137 //Adjust the center and radius depending on coordinate mode.
1139 radius *= TMath::Max(bbox.fWidth, bbox.fHeight);
1140 center.fX = bbox.fWidth * center.fX + bbox.fXMin;
1141 center.fY = bbox.fHeight * center.fY + bbox.fYMin;
1142 } else {
1143 const auto w = gPad->GetX2() - gPad->GetX1();
1144 const auto h = gPad->GetY2() - gPad->GetY1();
1145
1146 radius *= TMath::Max(w, h);
1147 center.fX *= w;
1148 center.fY *= h;
1149 }
1150 //Now for the gradient fill we switch into pixel coordinates:
1151 const auto pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1152 const auto pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1153 //
1156 //A new ortho projection:
1159 //
1160 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1161 //
1163 center.fX = gPad->XtoPixel(center.fX);
1164 center.fY = pixelH - gPad->YtoPixel(center.fY);
1165
1166 Double_t maxR = 0.;
1167 {
1168 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1169 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1170 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1171 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1172 //Get the longest distance from the center to the bounding box vertices
1173 //(this will be the maximum possible radius):
1174 const Double_t maxDistX = TMath::Max(TMath::Abs(center.fX - xMin),
1175 TMath::Abs(center.fX - xMax));
1176 const Double_t maxDistY = TMath::Max(TMath::Abs(center.fY - yMin),
1177 TMath::Abs(center.fY - yMax));
1179 }
1180
1181 //If gradient 'stops inside the polygon', we use
1182 //the solid fill for the area outside of radial gradient:
1183 const Bool_t solidFillAfter = maxR > radius;
1184 //We emulate a radial gradient using triangles and linear gradient:
1185 //TODO: Can be something smarter? (btw even 100 seems to be enough)
1186 const UInt_t nSlices = 500;
1187
1188 const auto nColors = grad->GetNumberOfSteps();
1189 //+1 - the strip from the last color's position to radius,
1190 //and (probably) + 1 for solidFillAfter.
1191 const auto nCircles = nColors + 1 + solidFillAfter;
1192
1193 //TODO: can locations be outside of [0., 1.] ???
1194 //at the moment I assume the answer is NO, NEVER.
1195 const auto locations = grad->GetColorPositions();
1196 // * 2 below == x,y
1197 std::vector<Double_t> circles(nSlices * nCircles * 2);
1198 const Double_t angle = TMath::TwoPi() / nSlices;
1199
1200 //"Main" circles (for colors at locations[i]).
1201 for (UInt_t i = 0; i < nColors; ++i) {
1202 const auto circle = &circles[i * nSlices * 2];
1203 //TODO: either check locations here or somewhere else.
1204 const auto r = radius * locations[i];
1205 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1206 circle[j] = center.fX + r * TMath::Cos(angle * j);
1207 circle[j + 1] = center.fY + r * TMath::Sin(angle * j);
1208 }
1209 //The "closing" vertices:
1210 circle[(nSlices - 1) * 2] = circle[0];
1211 circle[(nSlices - 1) * 2 + 1] = circle[1];
1212 }
1213
1214 {
1215 //The strip between lastPos and radius:
1216 const auto circle = &circles[nColors * nSlices * 2];
1217 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1218 circle[j] = center.fX + radius * TMath::Cos(angle * j);
1219 circle[j + 1] = center.fY + radius * TMath::Sin(angle * j);
1220 }
1221
1222 circle[(nSlices - 1) * 2] = circle[0];
1223 circle[(nSlices - 1) * 2 + 1] = circle[1];
1224 }
1225
1226 if (solidFillAfter) {
1227 //The strip after the radius:
1228 const auto circle = &circles[(nCircles - 1) * nSlices * 2];
1229 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1230 circle[j] = center.fX + maxR * TMath::Cos(angle * j);
1231 circle[j + 1] = center.fY + maxR * TMath::Sin(angle * j);
1232 }
1233
1234 circle[(nSlices - 1) * 2] = circle[0];
1235 circle[(nSlices - 1) * 2 + 1] = circle[1];
1236 }
1237
1238 //Now we draw:
1239 //1) triangle fan in the center (from center to the locations[1],
1240 // with a solid fill).
1241 //2) quad strips for colors.
1242 //3) additional quad strip from the lastLocation to the radius
1243 //4) additional quad strip (if any) from the radius to maxR.
1244
1245 //RGBA values:
1246 const auto rgba = grad->GetColors();
1247
1249 //TODO?
1251
1252 //Probably a degenerated case. Maybe not.
1255 glVertex2d(center.fX, center.fY);
1256
1257 for (UInt_t i = 0, e = nSlices * 2; i < e; i += 2)
1258 glVertex2dv(&circles[i]);
1259
1260 glEnd();
1261
1262 //No auto for circles, explicit types to have const Double_t * const, not Duble_t * const.
1263 for (UInt_t i = 0; i < nColors - 1; ++i) {
1264 const Double_t * const inner = &circles[i * nSlices * 2];
1265 const auto innerRGBA = rgba + i * 4;
1266 const auto outerRGBA = rgba + (i + 1) * 4;
1267 const Double_t * const outer = &circles[(i + 1) * nSlices * 2];
1268
1270 }
1271
1272 //Probably degenerated strip.
1273 {
1274 const Double_t * const inner = &circles[nSlices * (nColors - 1) * 2];
1275 const auto solidRGBA = rgba + (nColors - 1) * 4;
1276 const Double_t * const outer = &circles[nSlices * nColors * 2];
1277
1279 }
1280
1281 if (solidFillAfter) {
1282 const Double_t * const inner = &circles[nSlices * nColors * 2];
1283 const auto solidRGBA = rgba + (nColors - 1) * 4;
1284 const Double_t * const outer = &circles[nSlices * (nColors + 1) * 2];
1285
1287 }
1288
1291}
1292
1293////////////////////////////////////////////////////////////////////////////////
1294
1296 const Double_t *x, const Double_t *y)
1297{
1298 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1299 assert(n > 2 && "DrawGradient, invalid number of points");
1300 assert(x != nullptr && "DrawGradient, parameter 'x' is null");
1301 assert(y != nullptr && "DrawGradient, parameter 'y' is null");
1302
1303 //Now we fill the whole scene with one big rectangle
1304 //(group of rectangles) with a gradient fill using
1305 //stencil test.
1306
1307 //Find a bounding rect.
1308 const auto &bbox = Rgl::Pad::FindBoundingRect(n, x, y);
1309 //TODO: check the bbox??
1310
1311 //For the gradient fill we switch into the
1312 //pixel coordinates.
1315
1316 //A new ortho projection:
1319
1320 const Double_t pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1321 const Double_t pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1322 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1323
1324 //A new modelview:
1327 //
1328 TColorGradient::Point start = grad->GetStart();
1329 TColorGradient::Point end = grad->GetEnd();
1330
1331 //Change gradient coordinates from 'NDC' to pad coords:
1333 {
1334 const Double_t w = gPad->GetX2() - gPad->GetX1();
1335 const Double_t h = gPad->GetY2() - gPad->GetY1();
1336
1337 start.fX = start.fX * w;
1338 start.fY = start.fY * h;
1339 end.fX = end.fX * w;
1340 end.fY = end.fY * h;
1341 } else {
1342 start.fX = start.fX * bbox.fWidth + bbox.fXMin;
1343 start.fY = start.fY * bbox.fHeight + bbox.fYMin;
1344 end.fX = end.fX * bbox.fWidth + bbox.fXMin;
1345 end.fY = end.fY * bbox.fHeight + bbox.fYMin;
1346 }
1347
1348 //TODO: with a radial fill we'll have to extract the code
1349 // below into the separate function/and have additional function
1350 // for a radial gradient.
1351 //Now from pad to pixels:
1352 start.fX = gPad->XtoPixel(start.fX);
1353 start.fY = pixelH - gPad->YtoPixel(start.fY);
1354 end.fX = gPad->XtoPixel(end.fX);
1355 end.fY = pixelH - gPad->YtoPixel(end.fY);
1356 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1357 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1358 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1359 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1360 //
1361
1362 //TODO: check all calculations!
1363
1364 //Get the longest distance from the start point to the bounding box vertices:
1365 const Double_t maxDistX = TMath::Max(TMath::Abs(start.fX - xMin), TMath::Abs(start.fX - xMax));
1366 const Double_t maxDistY = TMath::Max(TMath::Abs(start.fY - yMin), TMath::Abs(start.fY - yMax));
1367
1368 const Double_t startEndLength = TMath::Sqrt((end.fX - start.fX) * (end.fX - start.fX) +
1369 (end.fY - start.fY) * (end.fY - start.fY));
1372
1373 //Boxes with a gradients to emulate gradient fill with many colors:
1374 const Double_t * const colorPositions = grad->GetColorPositions();
1375 std::vector<Double_t> gradBoxes(grad->GetNumberOfSteps() + 2);
1376 gradBoxes[0] = start.fY - h;
1377 for (unsigned i = 1; i <= grad->GetNumberOfSteps(); ++i)
1378 gradBoxes[i] = startEndLength * colorPositions[i - 1] + start.fY;
1379
1380 gradBoxes[grad->GetNumberOfSteps() + 1] = start.fY + h;
1381
1382 //Rotation angle - gradient's axis:
1383 Double_t angle = TMath::ACos((startEndLength * (end.fY - start.fY)) /
1385 if (end.fX > start.fX)
1386 angle *= -1;
1387
1388 glTranslated(start.fX, start.fY, 0.);
1389 glRotated(angle, 0., 0., 1.);
1390 glTranslated(-start.fX, -start.fY, 0.);
1391 //
1392 const Double_t * const rgba = grad->GetColors();
1393
1394 const unsigned nEdges = gradBoxes.size();
1395 const unsigned nColors = grad->GetNumberOfSteps();
1396 const Double_t xLeft = start.fX - h, xRight = start.fX + h;
1397
1399 //TODO?
1401
1404 rgba + (nColors - 1) * 4, rgba + (nColors - 1) * 4);
1405
1406 for (unsigned i = 1; i < nEdges - 2; ++i)
1408 xRight, rgba + (i - 1) * 4, rgba + i * 4);
1409
1412}
1413
1414////////////////////////////////////////////////////////////////////////////////
1415
1417{
1418 assert(n > 2 && "DrawTesselation, invalid number of points");
1419 assert(x != nullptr && "DrawTesselation, parameter 'x' is null");
1420 assert(y != nullptr && "DrawTesselation, parameter 'y' is null");
1421
1422 //Data for a tesselator:
1423 fVs.resize(n * 3);
1424
1425 for (Int_t i = 0; i < n; ++i) {
1426 fVs[i * 3] = x[i];
1427 fVs[i * 3 + 1] = y[i];
1428 fVs[i * 3 + 2] = 0.;
1429 }
1430
1431 //TODO: A very primitive way to tesselate - check what
1432 //kind of polygons we can really have from TPad/TCanvas.
1434 gluBeginPolygon(t);
1436
1437 for (Int_t i = 0; i < n; ++i)
1438 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
1439
1440 gluEndPolygon(t);
1441}
1442
1443
1444//Aux. functions.
1445namespace {
1446
1447template<class ValueType>
1448void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst)
1449{
1450 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
1451
1452 dst.resize(n);
1453 for (Int_t i = 0; i < n; ++i) {
1454 dst[i].fX = gPad->XtoPixel(x[i]);
1455 dst[i].fY = padH - gPad->YtoPixel(y[i]);
1456 }
1457}
1458
1459}
1460
#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:627
#define gROOT
Definition TROOT.h:414
#define gPad
#define gVirtualX
Definition TVirtualX.h:365
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
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.
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.
const TAttFill & GetAttFill() const override
Style_t GetMarkerStyle() const override
Font_t GetTextFont() const override
Width_t GetLineWidth() const override
void SetAttMarker(const TAttMarker &att) override
Set marker attributes.
void SetAttLine(const TAttLine &att) override
Set line attributes.
Color_t GetFillColor() const override
Float_t GetTextAngle() const override
Color_t GetTextColor() const override
Style_t GetLineStyle() const override
const TAttLine & GetAttLine() const override
Get line attributes.
Style_t GetFillStyle() const override
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