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#include "TImage.h"
26
27#include "TColorGradient.h"
28#include "TGLPadPainter.h"
29#include "TGLIncludes.h"
30#include "TGLUtil.h"
31#include "TMath.h"
32
33#include <glad/gl.h>
34
35namespace {
36
37////////////////////////////////////////////////////////////////////////////////
38///Not a bad idea to assert on gVirtualX != nullptr
39
41{
42 return dynamic_cast<TColorGradient *>(gROOT->GetColor(fillColorIndex));
43}
44
45}
46
47/** \class TGLPadPainter
48\ingroup opengl
49"Delegating" part of TGLPadPainter. Line/fill/etc. attributes can be
50set inside TPad, but not only there:
51many of them are set by base sub-objects of 2d primitives
52(2d primitives usually inherit TAttLine or TAttFill etc.). And these sub-objects
53call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
54it will be mess - at any moment I do not know, where to take line attribute - from
55gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
56*/
57
58
59////////////////////////////////////////////////////////////////////////////////
60
62 : fIsHollowArea(kFALSE),
63 fLocked(kTRUE)
64{
65 fVp[0] = fVp[1] = fVp[2] = fVp[3] = 0;
66 fWinContext = 0;
67}
68
69
70////////////////////////////////////////////////////////////////////////////////
71///Delegate to gVirtualX.
72
74{
75 // does not work this way
76 gVirtualX->SetOpacityW(fWinContext, percent);
77}
78
79////////////////////////////////////////////////////////////////////////////////
80///Delegate to gVirtualX.
81
83{
84 return gVirtualX->GetTextMagnitude();
85}
86
87////////////////////////////////////////////////////////////////////////////////
88/// Select pad where current painting will be performed
89
91{
92 // GL painter does not use proper id for sub-pads (see CreateDrawable)
93 // so one always use canvas ID to execute TVirtualX-specific commands
94 if (!fWinContext)
95 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
96}
97
98////////////////////////////////////////////////////////////////////////////////
99/// Set fill attributes
100
102{
104
106
107 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
108 if (fWinContext && gVirtualX)
109 gVirtualX->SetAttFill(fWinContext, att);
110}
111
112////////////////////////////////////////////////////////////////////////////////
113/// Set line attributes
114
116{
118
119 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
120 if (fWinContext && gVirtualX)
121 gVirtualX->SetAttLine(fWinContext, att);
122}
123
124////////////////////////////////////////////////////////////////////////////////
125/// Set marker attributes
126
128{
130
131 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
132 if (fWinContext && gVirtualX)
133 gVirtualX->SetAttMarker(fWinContext, att);
134}
135
136/*
137"Pixmap" part of TGLPadPainter.
138*/
139
140////////////////////////////////////////////////////////////////////////////////
141///Not required at the moment.
142
144{
145 // return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
146 return 0;
147}
148
149////////////////////////////////////////////////////////////////////////////////
150/// Resize a gVirtualX Pixmap.
151
153{
154 return gVirtualX->ResizePixmap(device, w, h);
155}
156
157////////////////////////////////////////////////////////////////////////////////
158/// Do nothing, sub-pads not cleared in GL
159
163
164////////////////////////////////////////////////////////////////////////////////
165/// Clear specified window - calling gVirtualX->ClearWindowW
166
168{
169 auto ctxt = gVirtualX->GetWindowContext(device);
170 if (ctxt)
171 gVirtualX->ClearWindowW(ctxt);
172}
173
174////////////////////////////////////////////////////////////////////////////////
175/// Returns true when cocoa backend is used
176
178{
179 return gVirtualX->InheritsFrom("TGCocoa");
180}
181
182////////////////////////////////////////////////////////////////////////////////
183///Not required at the moment.
184
185void TGLPadPainter::CopyDrawable(Int_t /* device */, Int_t /* px */, Int_t /* py */)
186{
187 // gVirtualX->CopyPixmapW(fWinContext, device, px, py);
188}
189
190////////////////////////////////////////////////////////////////////////////////
191///Not required at the moment.
192
194{
195 // gVirtualX->SelectWindow(device);
196 // gVirtualX->ClosePixmap();
197 fWinContext = 0;
198}
199
200////////////////////////////////////////////////////////////////////////////////
201///For gVirtualX this means select pixmap (or window)
202///and all subsequent drawings will go into
203///this pixmap. For OpenGL this means the change of
204///coordinate system and viewport.
205
207{
208 auto pad = dynamic_cast<TPad *>(gPad);
209 if (!fWinContext && pad)
210 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
211
212 if (fLocked)
213 return;
214
215 if (pad) {
216 // GL painter does not use proper id for sub-pads (see CreateDrawable)
217 // so one always use canvas ID to execute TVirtualX-specific commands
218 Int_t px = 0, py = 0;
219
220 pad->XYtoAbsPixel(pad->GetX1(), pad->GetY1(), px, py);
221
222 py = gPad->GetWh() - py;
223 //
226
227 glViewport(GLint(px * scale), GLint(py * scale),
228 GLsizei(gPad->GetWw() * pad->GetAbsWNDC() * scale),
229 GLsizei(gPad->GetWh() * pad->GetAbsHNDC() * scale));
230
233 glOrtho(pad->GetX1(), pad->GetX2(), pad->GetY1(), pad->GetY2(), -10., 10.);
234
237 glTranslated(0., 0., -1.);
238 } else {
239 ::Error("TGLPadPainter::SelectDrawable",
240 "function was called not from TPad or TCanvas code\n");
241 throw std::runtime_error("");
242 }
243}
244
245////////////////////////////////////////////////////////////////////////////////
246/// Call low-level update of selected drawable, redirect to gVirtualX.
247
249{
250 if (fWinContext)
251 gVirtualX->UpdateWindowW(fWinContext, mode);
252}
253
254
255////////////////////////////////////////////////////////////////////////////////
256/// Set drawing mode for specified device
257
259{
260 auto ctxt = fWinContext;
261 if (device)
262 ctxt = gVirtualX->GetWindowContext(device);
263 if (ctxt)
264 gVirtualX->SetDrawModeW(ctxt, (TVirtualX::EDrawMode) mode);
265}
266
267////////////////////////////////////////////////////////////////////////////////
268///Init gl-pad painter:
269///1. 2D painter does not use depth test, should not modify
270/// depth-buffer content (except initial cleanup).
271///2. Disable cull face.
272///3. Disable lighting.
273///4. Set viewport (to the whole canvas area).
274///5. Set camera.
275///6. Unlock painter.
276
278{
279 static bool gl_init = false;
280 if (!gl_init) {
282 if (version == 0)
283 Warning("TGLPadPainter::InitPainter", "GL initalization failed.");
284 else if (gDebug > 0)
285 Info("TGLPadPainter::InitPainter", "GL initalization successful.");
286 gl_init = true;
287 }
291
292 //Clear the buffer
293 glViewport(0, 0, GLsizei(gPad->GetWw()), GLsizei(gPad->GetWh()));
294
296 glClearColor(1.,1.,1.,1.);
299
302
303 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
304
307 glTranslated(0., 0., -1.);
308
309 fLocked = kFALSE;
310}
311
312////////////////////////////////////////////////////////////////////////////////
313///When TPad::Range for gPad is called, projection
314///must be changed in OpenGL.
315
317{
318 if (fLocked) return;
319
322
323 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
324
326}
327
328////////////////////////////////////////////////////////////////////////////////
329///Locked state of painter means, that
330///GL context can be invalid, so no GL calls
331///can be executed.
332
334{
335 if (fLocked) return;
336
337 glFinish();
338 fLocked = kTRUE;
339}
340
341/*
3422D primitives.
343*/
344
346
347////////////////////////////////////////////////////////////////////////////////
348///Draw line segment.
349
351{
352 if (fLocked) {
353 //GL pad painter can be called in non-standard situation:
354 //not from TPad::Paint, but
355 //from TView3D::ExecuteRotateView. This means in fact,
356 //that TView3D wants to draw itself in a XOR mode, via
357 //gVirtualX.
358 // TODO: only here set line attributes to virtual x
359 if (IsInvertMode())
360 gVirtualX->DrawLineW(fWinContext,
361 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
362 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2));
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 or interactive objects move
399 if (IsInvertMode())
400 gVirtualX->DrawLineW(fWinContext,
401 gPad->UtoAbsPixel(u1), gPad->VtoAbsPixel(v1),
402 gPad->UtoAbsPixel(u2), gPad->VtoAbsPixel(v2));
403 return;
404 }
405
407 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
408 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
409
410 glBegin(GL_LINES);
411 glVertex2d(gPad->GetX1() + u1 * xRange, gPad->GetY1() + v1 * yRange);
412 glVertex2d(gPad->GetX1() + u2 * xRange, gPad->GetY1() + v2 * yRange);
413 glEnd();
414}
415
416////////////////////////////////////////////////////////////////////////////////
417///Draw filled or hollow box.
418
420{
421 if (fLocked) {
422 //GL pad painter can be called in non-standard situation:
423 //not from TPad::Paint, but
424 //from TView3D::ExecuteRotateView. This means in fact,
425 //that TView3D wants to draw itself in a XOR mode, via
426 //gVirtualX.
427 // TODO: only here set line attributes to virtual x
428 if (IsInvertMode())
429 gVirtualX->DrawBoxW(fWinContext,
430 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
431 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2),
433 return;
434 }
435
437 Double_t xs[] = {x1, x2, x2, x1};
438 Double_t ys[] = {y1, y1, y2, y2};
440 return;
441 }
442
443 if (mode == kHollow) {
445 glBegin(GL_LINE_LOOP);
446 glVertex2d(x1, y1);
447 glVertex2d(x2, y1);
448 glVertex2d(x2, y2);
449 glVertex2d(x1, y2);
450 glEnd();
451 } else {
452 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE, &fGlFillAtt);//Set filling parameters.
453 glRectd(x1, y1, x2, y2);
454 }
455}
456
457////////////////////////////////////////////////////////////////////////////////
458///Draw tesselated polygon (probably, outline only).
459
461{
462 assert(x != nullptr && "DrawFillArea, parameter 'x' is null");
463 assert(y != nullptr && "DrawFillArea, parameter 'y' is null");
464
465 if (fLocked)
466 return;
467
468 if (n < 3) {
469 ::Error("TGLPadPainter::DrawFillArea",
470 "invalid number of points in a polygon");
471 return;
472 }
473
475 return DrawPolygonWithGradient(n, x, y);
476
477 if (fFullyTransparent) {
479 return DrawPolyLine(n, x, y);
480 }
481
483 DrawTesselation(n, x, y);
484}
485
486////////////////////////////////////////////////////////////////////////////////
487///Draw tesselated polygon (never called, probably, since TPad::PaintFillArea for floats
488///is deprecated).
489
491{
492 if (fLocked) return;
493
494 if (fFullyTransparent) {
496 return DrawPolyLine(n, x, y);
497 }
498
499 fVs.resize(n * 3);
500
501 for (Int_t i = 0; i < n; ++i) {
502 fVs[i * 3] = x[i];
503 fVs[i * 3 + 1] = y[i];
504 }
505
507
511
512 for (Int_t i = 0; i < n; ++i)
513 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
514
515
516 gluEndPolygon(t);
517}
518
519////////////////////////////////////////////////////////////////////////////////
520///Draw poly-line in user coordinates.
521
522template<class ValueType>
523void TGLPadPainter::DrawPolyLineHelper(Int_t n, const ValueType *x, const ValueType *y)
524{
525 if (fLocked) {
526 if (IsInvertMode() && (n > 1)) {
527 std::vector<TPoint> xy(n);
528 for (Int_t i = 0; i < n; ++i) {
529 xy[i].fX = (SCoord_t) gPad->XtoAbsPixel(x[i]);
530 xy[i].fY = (SCoord_t) gPad->YtoAbsPixel(y[i]);
531 }
532 gVirtualX->DrawPolyLineW(fWinContext, xy.size(), xy.data());
533 }
534 return;
535 }
536
538
539 glBegin(GL_LINE_STRIP);
540
541 for (Int_t i = 0; i < n; ++i)
542 glVertex2d(x[i], y[i]);
543
544 if (fIsHollowArea) {
545 glVertex2d(x[0], y[0]);
547 }
548 glEnd();
549
551 Double_t pointSize = GetAttLine().GetLineWidth();
557 glBegin(GL_POINTS);
558
559 for (Int_t i = 0; i < n; ++i)
560 glVertex2d(x[i], y[i]);
561
562 glEnd();
563 glPointSize(1.f);
564 }
565}
566
567////////////////////////////////////////////////////////////////////////////////
568/// Draw poly-line in user coordinates.
569
571{
573}
574
575////////////////////////////////////////////////////////////////////////////////
576/// Draw poly-line in user coordinates.
577
579{
581}
582
583////////////////////////////////////////////////////////////////////////////////
584///Poly line in NDC.
585
587{
588 if (fLocked) return;
589
591 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
592 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
593 const Double_t x1 = gPad->GetX1(), y1 = gPad->GetY1();
594
595 glBegin(GL_LINE_STRIP);
596
597 for (Int_t i = 0; i < n; ++i)
598 glVertex2d(x1 + u[i] * xRange, y1 + v[i] * yRange);
599
600 glEnd();
601}
602
603////////////////////////////////////////////////////////////////////////////////
604/// Returns true when invert mode is configured and painter in locked state
605/// Used when non-opaque of objects moving is involved
606
611
612////////////////////////////////////////////////////////////////////////////////
613///Poly-marker drawing
614
615template<class ValueType>
616void TGLPadPainter::DrawPolyMarkerHelper(Int_t n, const ValueType *x, const ValueType *y)
617{
618 std::vector<TPoint> poly(n);
619
620 if (fLocked) {
621 if (IsInvertMode()) {
622 for (Int_t i = 0; i < n; ++i) {
623 poly[i].fX = gPad->XtoAbsPixel(x[i]);
624 poly[i].fY = gPad->YtoAbsPixel(y[i]);
625 }
626 gVirtualX->DrawPolyMarkerW(fWinContext, poly.size(), poly.data());
627 }
628 return;
629 }
630
631 const UInt_t padH = gPad->GetPadHeight();
632
633 for (Int_t i = 0; i < n; ++i) {
634 poly[i].fX = gPad->XtoPixel(x[i]);
635 poly[i].fY = padH - gPad->YtoPixel(y[i]);
636 }
637
640 //
641 glOrtho(0, gPad->GetPadWidth(), 0, gPad->GetPadHeight(), -10., 10.);
642 //
644 //
646
647 Float_t rgba[4] = {};
651
654
656
659 glLineWidth(1.f);
660}
661
662////////////////////////////////////////////////////////////////////////////////
663///Poly-marker.
664
669
670////////////////////////////////////////////////////////////////////////////////
671///Poly-marker.
672
677
678////////////////////////////////////////////////////////////////////////////////
679/// Select specified font/size
680
682{
683 //10 is the first valid font index.
684 //20 is FreeSerifBold, as in TTF.cxx and in TGLFontManager.cxx.
685 //shift - is the shift to access "extended" fonts.
687
688 Int_t fontIndex = TMath::Max(Font_t(10), font);
689 if (fontIndex / 10 + shift > TGLFontManager::GetFontFileArray()->GetEntries())
690 fontIndex = 20 + shift * 10;
691 else
692 fontIndex += shift * 10;
693
694 Int_t textSize = TMath::Max(Int_t(tsize) - 1, 10);
695
697
699}
700
701////////////////////////////////////////////////////////////////////////////////
702/// Indicate that TTF can be used for text metrics
703/// Drawing done with FTGL which is based on Freetype library
704
706{
707 return kTRUE;
708}
709
710
711////////////////////////////////////////////////////////////////////////////////
712/// Helper function to draw text
713
714template<class Char>
716{
718
720 //
721 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
722 //
724
725 Float_t rgba[4] = {};
728
729 SelectGLFont(GetAttText().GetTextFont(), GetAttText().GetTextSizePixels(*gPad));
730
732
733 fF.PreRender();
734
735 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
736 fF.Render(text, gPad->XtoPixel(x), padH - gPad->YtoPixel(y), GetTextAngle(), GetTextMagnitude());
737
738 fF.PostRender();
740
742}
743
744////////////////////////////////////////////////////////////////////////////////
745///Draw text. This operation is especially
746///dangerous if in locked state -
747///ftgl will assert on zero texture size
748///(which is result of bad GL context).
749
751{
752 if (fLocked) return;
753
754 if (GetAttText().GetTextSize() > 0)
756}
757
758////////////////////////////////////////////////////////////////////////////////
759///Draw text. This operation is especially
760///dangerous if in locked state -
761///ftgl will assert on zero texture size
762///(which is result of bad GL context).
763
765{
766 if (fLocked) return;
767
768 if (GetAttText().GetTextSize() > 0)
770}
771
772////////////////////////////////////////////////////////////////////////////////
773///Draw text in NDC. This operation is especially
774///dangerous if in locked state -
775///ftgl will assert on zero texture size
776///(which is result of bad GL context).
777
779{
780 if (fLocked) return;
781
782 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
783 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
784 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
785}
786
787////////////////////////////////////////////////////////////////////////////////
788///Draw text in NDC. This operation is especially
789///dangerous if in locked state -
790///ftgl will assert on zero texture size
791///(which is result of bad GL context).
792
794{
795 if (fLocked) return;
796
797 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
798 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
799 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
800}
801
802////////////////////////////////////////////////////////////////////////////////
803///Save the projection matrix.
804///Attention! GL_PROJECTION will become the current matrix
805///after this call!
806
812
813////////////////////////////////////////////////////////////////////////////////
814///Restore the projection matrix.
815///Attention! GL_PROJECTION will become the current matrix
816///after this call!
817
823
824////////////////////////////////////////////////////////////////////////////////
825///Save the modelview matrix.
826///Attention! GL_MODELVIEW will become the current matrix
827///after this call!
828
834
835////////////////////////////////////////////////////////////////////////////////
836///Restore the modelview matrix.
837///Attention! GL_MODELVIEW will become the current matrix
838///after this call!
839
845
846////////////////////////////////////////////////////////////////////////////////
847///Extract and save the current viewport.
848
853
854////////////////////////////////////////////////////////////////////////////////
855///Restore the saved viewport.
856
858{
859 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
860}
861
862
863////////////////////////////////////////////////////////////////////////////////
864/// Draw image on the GL window
865
867{
868 Int_t width = img->GetWidth();
869 Int_t height = img->GetHeight();
870 auto bits = img->GetArgbArray();
871 if (bits)
872 DrawPixels((unsigned char *)bits, width, height, x, y, flags);
873}
874
875////////////////////////////////////////////////////////////////////////////////
876/// Using TImage save frame-buffer contents as a picture.
877
878void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
879{
880 auto canvas = pad->GetCanvas();
881 if (!canvas)
882 return;
883
884 canvas->Flush();
885
886 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
889 //In case GL_BGRA is not in gl.h (old windows' gl) - comment/uncomment lines.
890 //glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_BGRA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
891 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
892
893 std::unique_ptr<TImage> image(TImage::Create());
894 if (!image.get()) {
895 ::Error("TGLPadPainter::SaveImage", "TImage creation failed");
896 return;
897 }
898
899 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
900 UInt_t *argb = image->GetArgbArray();
901
902 if (!argb) {
903 ::Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
904 return;
905 }
906
907 const Int_t nLines = canvas->GetWh();
908 const Int_t nPixels = canvas->GetWw();
909
910 for (Int_t i = 0; i < nLines; ++i) {
911 Int_t base = (nLines - 1 - i) * nPixels;
912 for (Int_t j = 0; j < nPixels; ++j, ++base) {
913 //Uncomment/comment if you don't have GL_BGRA.
914
915 const UInt_t pix = buff[base];
916 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
917 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
918
919 //argb[i * nPixels + j] = buff[base];
920 argb[i * nPixels + j] = bgra;
921 }
922 }
923
924 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
925}
926
927////////////////////////////////////////////////////////////////////////////////
928
931{
932 if (fLocked)
933 return;
934
935 if (!pixelData) {
936 //I'd prefer an assert.
937 ::Error("TGLPadPainter::DrawPixels", "pixel data is null");
938 return;
939 }
940
941 if (std::numeric_limits<UInt_t>::digits >= 32) {
942 //TASImage uses bit 31 as ...
943 //alpha channel flag! FUUUUUUUUUUUUU ..... !!!
944 CLRBIT(width, 31);
945 CLRBIT(height, 31);
946 }
947
948 if (!width) {
949 //Assert is better.
950 ::Error("TGLPadPainter::DrawPixels", "invalid width");
951 return;
952 }
953
954 if (!height) {
955 //Assert is better.
956 ::Error("TGLPadPainter::DrawPixels", "invalid height");
957 return;
958 }
959
960 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
961 //TASImage passes pixel coordinates in pad's pixmap coordinate space.
962 //While glRasterPosX said to work with 'window' coordinates,
963 //that's a lie :) it does not :)
964
965 const Double_t rasterX = Double_t(dstX) / (pad->GetAbsWNDC() * pad->GetWw()) *
966 (pad->GetX2() - pad->GetX1()) + pad->GetX1();
967
968 const Double_t yRange = pad->GetY2() - pad->GetY1();
969 const Double_t rasterY = yRange - Double_t(dstY + height) / (pad->GetAbsHNDC() * pad->GetWh()) * yRange +
970 pad->GetY1();
971
972 GLdouble oldPos[4] = {};
973 //Save the previous raster pos.
975
977 //Stupid asimage provides us upside-down image.
978 std::vector<unsigned char> upsideDownImage(4 * width * height);
979 const unsigned char *srcLine = pixelData + 4 * width * (height - 1);
980 unsigned char *dstLine = &upsideDownImage[0];
981 for (UInt_t i = 0; i < height; ++i, srcLine -= 4 * width, dstLine += 4 * width)
982 std::copy(srcLine, srcLine + 4 * width, dstLine);
983
984 if (enableBlending) {
987 }
988
990
991 if (enableBlending)
993
994 //Restore raster pos.
996 } else
997 ::Error("TGLPadPainter::DrawPixels", "no pad found to draw");
998}
999
1000//Aux. functions - gradient and solid fill of arbitrary area.
1001
1002////////////////////////////////////////////////////////////////////////////////
1003///At the moment I assume both linear and radial gradients will work the same way -
1004///using a stencil buffer and some big rectangle(s) to fill with a gradient.
1005///Thus I have a 'common' part - the part responsible for a stencil test.
1006
1008{
1009 assert(n > 2 && "DrawPolygonWithGradient, invalid number of points");
1010 assert(x != nullptr && "DrawPolygonWithGradient, parameter 'x' is null");
1011 assert(y != nullptr && "DrawPolygonWithGradient, parameter 'y' is null");
1012
1013 auto grad = dynamic_cast<TColorGradient *>(gROOT->GetColor(fGlFillAtt.GetFillColor()));
1014 assert(grad != nullptr && "DrawPolygonWithGradient, the current fill color is not a gradient fill");
1015
1016 if (fLocked)
1017 return;
1018
1019 //Now, some magic!
1021
1022 //TODO: check that the state is restored back correctly after
1023 // we done with a gradient.
1024 //TODO: make sure that we have glDepthMask set to false in general!
1026
1027 glStencilFunc(GL_NEVER, 1, 0xFF);
1028 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);// draw 1s on test fail (always)
1029 //Draw stencil pattern
1030 glStencilMask(0xFF);
1032
1033 //Draw our polygon into the stencil buffer:
1034 DrawTesselation(n, x, y);
1035
1037 glStencilMask(0x00);
1038 //Draw where stencil's value is 0
1039 glStencilFunc(GL_EQUAL, 0, 0xFF);
1040 //Draw only where stencil's value is 1
1041 glStencilFunc(GL_EQUAL, 1, 0xFF);
1042
1043 //At the moment radial gradient is derived from linear - it was convenient
1044 //at some point, but in fact it was a bad idea. And now I have to
1045 //first check radial gradient.
1046 //TODO: TRadialGradient must inherit TColorGradient directly.
1047 const TRadialGradient * const rGrad = dynamic_cast<const TRadialGradient *>(grad);
1048 if (rGrad)
1049 DrawGradient(rGrad, n, x, y);
1050 else {
1051 const TLinearGradient * const lGrad = dynamic_cast<const TLinearGradient *>(grad);
1052 assert(lGrad != nullptr && "DrawPolygonWithGradient, unknown gradient type");
1053 DrawGradient(lGrad, n, x, y);
1054 }
1055}
1056
1057////////////////////////////////////////////////////////////////////////////////
1058
1060 const Double_t *xs, const Double_t *ys)
1061{
1062 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1063 assert(nPoints > 2 && "DrawGradient, invalid number of points");
1064 assert(xs != nullptr && "DrawGradient, parameter 'xs' is null");
1065 assert(ys != nullptr && "DrawGradient, parameter 'ys' is null");
1066
1068 ::Warning("TGLPadPainter::DrawGradient",
1069 "extended radial gradient is not supported");//yet?
1070 return;
1071 }
1072
1073 //TODO: check the polygon's bbox!
1074 const auto &bbox = Rgl::Pad::FindBoundingRect(nPoints, xs, ys);
1075 //
1076 auto center = grad->GetCenter();
1077 auto radius = grad->GetRadius();
1078 //Adjust the center and radius depending on coordinate mode.
1080 radius *= TMath::Max(bbox.fWidth, bbox.fHeight);
1081 center.fX = bbox.fWidth * center.fX + bbox.fXMin;
1082 center.fY = bbox.fHeight * center.fY + bbox.fYMin;
1083 } else {
1084 const auto w = gPad->GetX2() - gPad->GetX1();
1085 const auto h = gPad->GetY2() - gPad->GetY1();
1086
1087 radius *= TMath::Max(w, h);
1088 center.fX *= w;
1089 center.fY *= h;
1090 }
1091 //Now for the gradient fill we switch into pixel coordinates:
1092 const auto pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1093 const auto pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1094 //
1097 //A new ortho projection:
1100 //
1101 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1102 //
1104 center.fX = gPad->XtoPixel(center.fX);
1105 center.fY = pixelH - gPad->YtoPixel(center.fY);
1106
1107 Double_t maxR = 0.;
1108 {
1109 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1110 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1111 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1112 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1113 //Get the longest distance from the center to the bounding box vertices
1114 //(this will be the maximum possible radius):
1115 const Double_t maxDistX = TMath::Max(TMath::Abs(center.fX - xMin),
1116 TMath::Abs(center.fX - xMax));
1117 const Double_t maxDistY = TMath::Max(TMath::Abs(center.fY - yMin),
1118 TMath::Abs(center.fY - yMax));
1120 }
1121
1122 //If gradient 'stops inside the polygon', we use
1123 //the solid fill for the area outside of radial gradient:
1124 const Bool_t solidFillAfter = maxR > radius;
1125 //We emulate a radial gradient using triangles and linear gradient:
1126 //TODO: Can be something smarter? (btw even 100 seems to be enough)
1127 const UInt_t nSlices = 500;
1128
1129 const auto nColors = grad->GetNumberOfSteps();
1130 //+1 - the strip from the last color's position to radius,
1131 //and (probably) + 1 for solidFillAfter.
1132 const auto nCircles = nColors + 1 + solidFillAfter;
1133
1134 //TODO: can locations be outside of [0., 1.] ???
1135 //at the moment I assume the answer is NO, NEVER.
1136 const auto locations = grad->GetColorPositions();
1137 // * 2 below == x,y
1138 std::vector<Double_t> circles(nSlices * nCircles * 2);
1139 const Double_t angle = TMath::TwoPi() / nSlices;
1140
1141 //"Main" circles (for colors at locations[i]).
1142 for (UInt_t i = 0; i < nColors; ++i) {
1143 const auto circle = &circles[i * nSlices * 2];
1144 //TODO: either check locations here or somewhere else.
1145 const auto r = radius * locations[i];
1146 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1147 circle[j] = center.fX + r * TMath::Cos(angle * j);
1148 circle[j + 1] = center.fY + r * TMath::Sin(angle * j);
1149 }
1150 //The "closing" vertices:
1151 circle[(nSlices - 1) * 2] = circle[0];
1152 circle[(nSlices - 1) * 2 + 1] = circle[1];
1153 }
1154
1155 {
1156 //The strip between lastPos and radius:
1157 const auto circle = &circles[nColors * nSlices * 2];
1158 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1159 circle[j] = center.fX + radius * TMath::Cos(angle * j);
1160 circle[j + 1] = center.fY + radius * TMath::Sin(angle * j);
1161 }
1162
1163 circle[(nSlices - 1) * 2] = circle[0];
1164 circle[(nSlices - 1) * 2 + 1] = circle[1];
1165 }
1166
1167 if (solidFillAfter) {
1168 //The strip after the radius:
1169 const auto circle = &circles[(nCircles - 1) * nSlices * 2];
1170 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1171 circle[j] = center.fX + maxR * TMath::Cos(angle * j);
1172 circle[j + 1] = center.fY + maxR * TMath::Sin(angle * j);
1173 }
1174
1175 circle[(nSlices - 1) * 2] = circle[0];
1176 circle[(nSlices - 1) * 2 + 1] = circle[1];
1177 }
1178
1179 //Now we draw:
1180 //1) triangle fan in the center (from center to the locations[1],
1181 // with a solid fill).
1182 //2) quad strips for colors.
1183 //3) additional quad strip from the lastLocation to the radius
1184 //4) additional quad strip (if any) from the radius to maxR.
1185
1186 //RGBA values:
1187 const auto rgba = grad->GetColors();
1188
1190 //TODO?
1192
1193 //Probably a degenerated case. Maybe not.
1196 glVertex2d(center.fX, center.fY);
1197
1198 for (UInt_t i = 0, e = nSlices * 2; i < e; i += 2)
1199 glVertex2dv(&circles[i]);
1200
1201 glEnd();
1202
1203 //No auto for circles, explicit types to have const Double_t * const, not Duble_t * const.
1204 for (UInt_t i = 0; i < nColors - 1; ++i) {
1205 const Double_t * const inner = &circles[i * nSlices * 2];
1206 const auto innerRGBA = rgba + i * 4;
1207 const auto outerRGBA = rgba + (i + 1) * 4;
1208 const Double_t * const outer = &circles[(i + 1) * nSlices * 2];
1209
1211 }
1212
1213 //Probably degenerated strip.
1214 {
1215 const Double_t * const inner = &circles[nSlices * (nColors - 1) * 2];
1216 const auto solidRGBA = rgba + (nColors - 1) * 4;
1217 const Double_t * const outer = &circles[nSlices * nColors * 2];
1218
1220 }
1221
1222 if (solidFillAfter) {
1223 const Double_t * const inner = &circles[nSlices * nColors * 2];
1224 const auto solidRGBA = rgba + (nColors - 1) * 4;
1225 const Double_t * const outer = &circles[nSlices * (nColors + 1) * 2];
1226
1228 }
1229
1232}
1233
1234////////////////////////////////////////////////////////////////////////////////
1235
1237 const Double_t *x, const Double_t *y)
1238{
1239 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1240 assert(n > 2 && "DrawGradient, invalid number of points");
1241 assert(x != nullptr && "DrawGradient, parameter 'x' is null");
1242 assert(y != nullptr && "DrawGradient, parameter 'y' is null");
1243
1244 //Now we fill the whole scene with one big rectangle
1245 //(group of rectangles) with a gradient fill using
1246 //stencil test.
1247
1248 //Find a bounding rect.
1249 const auto &bbox = Rgl::Pad::FindBoundingRect(n, x, y);
1250 //TODO: check the bbox??
1251
1252 //For the gradient fill we switch into the
1253 //pixel coordinates.
1256
1257 //A new ortho projection:
1260
1261 const Double_t pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1262 const Double_t pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1263 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1264
1265 //A new modelview:
1268 //
1269 TColorGradient::Point start = grad->GetStart();
1270 TColorGradient::Point end = grad->GetEnd();
1271
1272 //Change gradient coordinates from 'NDC' to pad coords:
1274 {
1275 const Double_t w = gPad->GetX2() - gPad->GetX1();
1276 const Double_t h = gPad->GetY2() - gPad->GetY1();
1277
1278 start.fX = start.fX * w;
1279 start.fY = start.fY * h;
1280 end.fX = end.fX * w;
1281 end.fY = end.fY * h;
1282 } else {
1283 start.fX = start.fX * bbox.fWidth + bbox.fXMin;
1284 start.fY = start.fY * bbox.fHeight + bbox.fYMin;
1285 end.fX = end.fX * bbox.fWidth + bbox.fXMin;
1286 end.fY = end.fY * bbox.fHeight + bbox.fYMin;
1287 }
1288
1289 //TODO: with a radial fill we'll have to extract the code
1290 // below into the separate function/and have additional function
1291 // for a radial gradient.
1292 //Now from pad to pixels:
1293 start.fX = gPad->XtoPixel(start.fX);
1294 start.fY = pixelH - gPad->YtoPixel(start.fY);
1295 end.fX = gPad->XtoPixel(end.fX);
1296 end.fY = pixelH - gPad->YtoPixel(end.fY);
1297 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1298 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1299 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1300 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1301 //
1302
1303 //TODO: check all calculations!
1304
1305 //Get the longest distance from the start point to the bounding box vertices:
1306 const Double_t maxDistX = TMath::Max(TMath::Abs(start.fX - xMin), TMath::Abs(start.fX - xMax));
1307 const Double_t maxDistY = TMath::Max(TMath::Abs(start.fY - yMin), TMath::Abs(start.fY - yMax));
1308
1309 const Double_t startEndLength = TMath::Sqrt((end.fX - start.fX) * (end.fX - start.fX) +
1310 (end.fY - start.fY) * (end.fY - start.fY));
1313
1314 //Boxes with a gradients to emulate gradient fill with many colors:
1315 const Double_t * const colorPositions = grad->GetColorPositions();
1316 std::vector<Double_t> gradBoxes(grad->GetNumberOfSteps() + 2);
1317 gradBoxes[0] = start.fY - h;
1318 for (unsigned i = 1; i <= grad->GetNumberOfSteps(); ++i)
1319 gradBoxes[i] = startEndLength * colorPositions[i - 1] + start.fY;
1320
1321 gradBoxes[grad->GetNumberOfSteps() + 1] = start.fY + h;
1322
1323 //Rotation angle - gradient's axis:
1324 Double_t angle = TMath::ACos((startEndLength * (end.fY - start.fY)) /
1326 if (end.fX > start.fX)
1327 angle *= -1;
1328
1329 glTranslated(start.fX, start.fY, 0.);
1330 glRotated(angle, 0., 0., 1.);
1331 glTranslated(-start.fX, -start.fY, 0.);
1332 //
1333 const Double_t * const rgba = grad->GetColors();
1334
1335 const unsigned nEdges = gradBoxes.size();
1336 const unsigned nColors = grad->GetNumberOfSteps();
1337 const Double_t xLeft = start.fX - h, xRight = start.fX + h;
1338
1340 //TODO?
1342
1345 rgba + (nColors - 1) * 4, rgba + (nColors - 1) * 4);
1346
1347 for (unsigned i = 1; i < nEdges - 2; ++i)
1349 xRight, rgba + (i - 1) * 4, rgba + i * 4);
1350
1353}
1354
1355////////////////////////////////////////////////////////////////////////////////
1356
1358{
1359 assert(n > 2 && "DrawTesselation, invalid number of points");
1360 assert(x != nullptr && "DrawTesselation, parameter 'x' is null");
1361 assert(y != nullptr && "DrawTesselation, parameter 'y' is null");
1362
1363 //Data for a tesselator:
1364 fVs.resize(n * 3);
1365
1366 for (Int_t i = 0; i < n; ++i) {
1367 fVs[i * 3] = x[i];
1368 fVs[i * 3 + 1] = y[i];
1369 fVs[i * 3 + 2] = 0.;
1370 }
1371
1372 //TODO: A very primitive way to tesselate - check what
1373 //kind of polygons we can really have from TPad/TCanvas.
1375 gluBeginPolygon(t);
1377
1378 for (Int_t i = 0; i < n; ++i)
1379 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
1380
1381 gluEndPolygon(t);
1382}
1383
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
short Color_t
Color number (short)
Definition RtypesCore.h:100
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:61
short Width_t
Line width (short)
Definition RtypesCore.h:99
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:72
short Font_t
Font number (short)
Definition RtypesCore.h:96
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
short SCoord_t
Screen coordinates (short)
Definition RtypesCore.h:101
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
#define CLRBIT(n, i)
Definition Rtypes.h:93
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
const Double_t lineWidthTS
#define GL_BGRA
Definition TGLViewer.cxx:61
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void pix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint xy
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t width
Option_t Option_t TPoint TPoint percent
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint DrawText
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
Option_t Option_t TPoint TPoint const char text
Option_t Option_t TPoint TPoint const char y1
char name[80]
Definition TGX11.cxx:142
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:792
#define gROOT
Definition TROOT.h:417
#define gPad
#define gVirtualX
Definition TVirtualX.h:379
Double_t GetMaxLineWidth() const
Double_t GetMaxPointSize() const
static void DrawMarkers(UInt_t n, const TPoint *xy, const TAttMarker &attr)
Auxiliary class to draw markers in a gl-pad.
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:22
static Width_t GetMarkerLineWidth(Style_t style)
Internal helper function that returns the line width of the given marker style (0 = filled marker)
TColorGradient extends basic TColor.
const Double_t * GetColors() const
Get colors.
SizeType_t GetNumberOfSteps() const
Get number of steps.
ECoordinateMode GetCoordinateMode() const
Get coordinate mode.
const Double_t * GetColorPositions() const
Get color positions.
void RegisterFont(Int_t size, Int_t file, TGLFont::EMode mode, TGLFont &out)
Provide font with given size, file and FTGL class.
static Int_t GetExtendedFontStartIndex()
static const char * GetFontNameFromId(Int_t)
Get font name from TAttAxis font id.
static TObjArray * GetFontFileArray()
Get id to file name map.
void SetTextAlign(UInt_t align)
void Render(const char *txt, Double_t x, Double_t y, Double_t angle, Double_t mgn) const
virtual void PostRender() const
Reset GL state after FTFont rendering.
virtual void PreRender(Bool_t autoLight=kTRUE, Bool_t lightOn=kFALSE) const
Set-up GL state before FTFont rendering.
void DrawText(Double_t x, Double_t y, const char *text, ETextMode mode) override
Draw text.
void DrawPolyMarkerHelper(Int_t n, const ValueType *x, const ValueType *y)
Poly-marker drawing.
void SetDrawMode(Int_t device, Int_t mode) override
Set drawing mode for specified device.
void DrawPixels(const unsigned char *pixelData, UInt_t width, UInt_t height, Int_t dstX, Int_t dstY, Bool_t enableBlending) override
Int_t ResizeDrawable(Int_t device, UInt_t w, UInt_t h) override
Resize a gVirtualX Pixmap.
void DestroyDrawable(Int_t device) override
Not required at the moment.
void DrawGradient(const TLinearGradient *gradient, Int_t n, const Double_t *x, const Double_t *y)
Rgl::Pad::Tesselator fTess
void SelectGLFont(Font_t font, Float_t size)
Select specified font/size.
void DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2) override
Draw line segment in NDC coordinates.
WinContext_t fWinContext
void DrawTextHelper(Double_t x, Double_t y, const Char_t *text, ETextMode mode)
void DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EBoxMode mode) override
Draw filled or hollow box.
void SetAttLine(const TAttLine &att) override
Set line attributes.
TAttFill fGlFillAtt
void DrawPolygonWithGradient(Int_t n, const Double_t *x, const Double_t *y)
At the moment I assume both linear and radial gradients will work the same way - using a stencil buff...
Bool_t IsInvertMode()
Returns true when invert mode is configured and painter in locked state Used when non-opaque of objec...
void InvalidateCS() override
When TPad::Range for gPad is called, projection must be changed in OpenGL.
void ClearDrawable() override
Do nothing, sub-pads not cleared in GL.
void ClearWindow(Int_t device) override
Clear specified window - calling gVirtualX->ClearWindowW.
void DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v) override
Poly line in NDC.
void OnPad(TVirtualPad *) override
Select pad where current painting will be performed.
void DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y) override
Draw poly-line in user coordinates.
void DrawImage(TImage *img, Int_t x, Int_t y, Int_t flags=0) override
Draw image on the GL window.
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
void SaveViewport()
Extract and save the current viewport.
void CopyDrawable(Int_t device, Int_t px, Int_t py) override
Not required at the moment.
void SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const override
Using TImage save frame-buffer contents as a picture.
void DrawFillArea(Int_t n, const Double_t *x, const Double_t *y) override
Draw tesselated polygon (probably, outline only).
void DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y) override
Poly-marker.
void DrawPolyLineHelper(Int_t n, const ValueType *x, const ValueType *y)
Draw poly-line in user coordinates.
void UpdateDrawable(Int_t mode) override
Call low-level update of selected drawable, redirect to gVirtualX.
void RestoreProjectionMatrix() const
Restore the projection matrix.
void SetAttMarker(const TAttMarker &att) override
Set marker attributes.
void LockPainter() override
Locked state of painter means, that GL context can be invalid, so no GL calls can be executed.
Float_t GetTextMagnitude() const override
Delegate to gVirtualX.
void DrawTesselation(Int_t n, const Double_t *x, const Double_t *y)
Bool_t HasTTFonts() const override
Indicate that TTF can be used for text metrics Drawing done with FTGL which is based on Freetype libr...
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
An abstract interface to image processing library.
Definition TImage.h:29
EImageFileTypes
Definition TImage.h:36
static TImage * Create()
Create an image.
Definition TImage.cxx:34
const Point & GetEnd() const
Get end.
const Point & GetStart() const
Get start.
void SetAttFill(const TAttFill &att) override
Set fill attributes.
Color_t GetMarkerColor() const override
const TAttText & GetAttText() const override
Get text attributes.
Short_t GetTextAlign() const override
const TAttMarker & GetAttMarker() const override
Get marker attributes.
Style_t GetMarkerStyle() const override
Font_t GetTextFont() const override
Width_t GetLineWidth() const override
Bool_t fFullyTransparent
if transformed fill attributes fully transparent
void SetAttMarker(const TAttMarker &att) override
Set marker attributes.
void SetAttLine(const TAttLine &att) override
Set line attributes.
Float_t GetTextAngle() const override
TAttFill GetAttFillInternal(Bool_t with_transparency)
Returns fill attributes after modification Checks for special fill styles 4000 .
Color_t GetTextColor() const override
Style_t GetLineStyle() const override
const TAttLine & GetAttLine() const override
Get line attributes.
Float_t GetTextSize() const override
The most important graphics class in the ROOT system.
Definition TPad.h:28
SCoord_t fY
Definition TPoint.h:36
SCoord_t fX
Definition TPoint.h:35
Double_t GetRadius() const
Get radius.
const Point & GetCenter() const
Get center.
EGradientType GetGradientType() const
Get gradient type.
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
BoundingRect< ValueType > FindBoundingRect(Int_t nPoints, const ValueType *xs, const ValueType *ys)
void ExtractRGBA(Color_t colorIndex, Float_t *rgba)
void DrawQuadStripWithRadialGradientFill(unsigned nPoints, const Double_t *inner, const Double_t *innerRGBA, const Double_t *outer, const Double_t *outerRGBA)
TODO: is it possible to use GLdouble to avoid problems with Double_t/GLdouble if they are not the sam...
Definition TGLUtil.cxx:3216
void DrawBoxWithGradientFill(Double_t y1, Double_t y2, Double_t x1, Double_t x2, const Double_t *rgba1, const Double_t *rgba2)
Definition TGLUtil.cxx:3196
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Definition TMath.h:645
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:675
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:607
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:601
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