Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGLPadPainter.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Timur Pocheptsov 06/05/2009
3
4/*************************************************************************
5 * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <stdexcept>
13#include <cassert>
14#include <limits>
15#include <memory>
16#include <vector>
17
18#include "TAttMarker.h"
19#include "TVirtualX.h"
20#include "TError.h"
21#include "TImage.h"
22#include "TROOT.h"
23#include "TPad.h"
24#include "TCanvas.h"
25
26#include "TColorGradient.h"
27#include "TGLPadPainter.h"
28#include "TGLIncludes.h"
29#include "TGLUtil.h"
30#include "TMath.h"
31
32#include <glad/gl.h>
33
34namespace {
35
36////////////////////////////////////////////////////////////////////////////////
37///Not a bad idea to assert on gVirtualX != nullptr
38
40{
41 return dynamic_cast<TColorGradient *>(gROOT->GetColor(fillColorIndex));
42}
43
44}
45
46/** \class TGLPadPainter
47\ingroup opengl
48"Delegating" part of TGLPadPainter. Line/fill/etc. attributes can be
49set inside TPad, but not only there:
50many of them are set by base sub-objects of 2d primitives
51(2d primitives usually inherit TAttLine or TAttFill etc.). And these sub-objects
52call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
53it will be mess - at any moment I do not know, where to take line attribute - from
54gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
55*/
56
57
58////////////////////////////////////////////////////////////////////////////////
59
61 : fIsHollowArea(kFALSE),
62 fLocked(kTRUE)
63{
64 fVp[0] = fVp[1] = fVp[2] = fVp[3] = 0;
65 fWinContext = 0;
66}
67
68
69////////////////////////////////////////////////////////////////////////////////
70///Delegate to gVirtualX.
71
73{
74 // does not work this way
75 gVirtualX->SetOpacityW(fWinContext, percent);
76}
77
78////////////////////////////////////////////////////////////////////////////////
79///Delegate to gVirtualX.
80
82{
83 return gVirtualX->GetTextMagnitude();
84}
85
86////////////////////////////////////////////////////////////////////////////////
87/// Select pad where current painting will be performed
88
90{
91 // GL painter does not use proper id for sub-pads (see CreateDrawable)
92 // so one always use canvas ID to execute TVirtualX-specific commands
93 if (!fWinContext)
94 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
95}
96
97////////////////////////////////////////////////////////////////////////////////
98/// Set fill attributes
99
101{
103
105
106 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
107 if (fWinContext && gVirtualX)
108 gVirtualX->SetAttFill(fWinContext, att);
109}
110
111////////////////////////////////////////////////////////////////////////////////
112/// Set line attributes
113
115{
117
118 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
119 if (fWinContext && gVirtualX)
120 gVirtualX->SetAttLine(fWinContext, att);
121}
122
123////////////////////////////////////////////////////////////////////////////////
124/// Set marker attributes
125
127{
129
130 // TODO: dismiss in the future, gVirtualX attributes not needed in GL
131 if (fWinContext && gVirtualX)
132 gVirtualX->SetAttMarker(fWinContext, att);
133}
134
135/*
136"Pixmap" part of TGLPadPainter.
137*/
138
139////////////////////////////////////////////////////////////////////////////////
140///Not required at the moment.
141
143{
144 // return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
145 return 0;
146}
147
148////////////////////////////////////////////////////////////////////////////////
149/// Resize a gVirtualX Pixmap.
150
152{
153 return gVirtualX->ResizePixmap(device, w, h);
154}
155
156////////////////////////////////////////////////////////////////////////////////
157/// Do nothing, sub-pads not cleared in GL
158
162
163////////////////////////////////////////////////////////////////////////////////
164/// Clear specified window - calling gVirtualX->ClearWindowW
165
167{
168 auto ctxt = gVirtualX->GetWindowContext(device);
169 if (ctxt)
170 gVirtualX->ClearWindowW(ctxt);
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Returns true when cocoa backend is used
175
177{
178 return gVirtualX->InheritsFrom("TGCocoa");
179}
180
181////////////////////////////////////////////////////////////////////////////////
182///Not required at the moment.
183
184void TGLPadPainter::CopyDrawable(Int_t /* device */, Int_t /* px */, Int_t /* py */)
185{
186 // gVirtualX->CopyPixmapW(fWinContext, device, px, py);
187}
188
189////////////////////////////////////////////////////////////////////////////////
190///Not required at the moment.
191
193{
194 // gVirtualX->SelectWindow(device);
195 // gVirtualX->ClosePixmap();
196 fWinContext = 0;
197}
198
199////////////////////////////////////////////////////////////////////////////////
200///For gVirtualX this means select pixmap (or window)
201///and all subsequent drawings will go into
202///this pixmap. For OpenGL this means the change of
203///coordinate system and viewport.
204
206{
207 auto pad = dynamic_cast<TPad *>(gPad);
208 if (!fWinContext && pad)
209 fWinContext = gVirtualX->GetWindowContext(pad->GetCanvasID());
210
211 if (fLocked)
212 return;
213
214 if (pad) {
215 // GL painter does not use proper id for sub-pads (see CreateDrawable)
216 // so one always use canvas ID to execute TVirtualX-specific commands
217 Int_t px = 0, py = 0;
218
219 pad->XYtoAbsPixel(pad->GetX1(), pad->GetY1(), px, py);
220
221 py = gPad->GetWh() - py;
222 //
225
226 glViewport(GLint(px * scale), GLint(py * scale),
227 GLsizei(gPad->GetWw() * pad->GetAbsWNDC() * scale),
228 GLsizei(gPad->GetWh() * pad->GetAbsHNDC() * scale));
229
232 glOrtho(pad->GetX1(), pad->GetX2(), pad->GetY1(), pad->GetY2(), -10., 10.);
233
236 glTranslated(0., 0., -1.);
237 } else {
238 ::Error("TGLPadPainter::SelectDrawable",
239 "function was called not from TPad or TCanvas code\n");
240 throw std::runtime_error("");
241 }
242}
243
244////////////////////////////////////////////////////////////////////////////////
245/// Call low-level update of selected drawable, redirect to gVirtualX.
246
248{
249 if (fWinContext)
250 gVirtualX->UpdateWindowW(fWinContext, mode);
251}
252
253
254////////////////////////////////////////////////////////////////////////////////
255/// Set drawing mode for specified device
256
258{
259 auto ctxt = fWinContext;
260 if (device)
261 ctxt = gVirtualX->GetWindowContext(device);
262 if (ctxt)
263 gVirtualX->SetDrawModeW(ctxt, (TVirtualX::EDrawMode) mode);
264}
265
266////////////////////////////////////////////////////////////////////////////////
267///Init gl-pad painter:
268///1. 2D painter does not use depth test, should not modify
269/// depth-buffer content (except initial cleanup).
270///2. Disable cull face.
271///3. Disable lighting.
272///4. Set viewport (to the whole canvas area).
273///5. Set camera.
274///6. Unlock painter.
275
277{
278 static bool gl_init = false;
279 if (!gl_init) {
281 if (version == 0)
282 Warning("TGLPadPainter::InitPainter", "GL initalization failed.");
283 else if (gDebug > 0)
284 Info("TGLPadPainter::InitPainter", "GL initalization successful.");
285 gl_init = true;
286 }
290
291 //Clear the buffer
292 glViewport(0, 0, GLsizei(gPad->GetWw()), GLsizei(gPad->GetWh()));
293
295 glClearColor(1.,1.,1.,1.);
298
301
302 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
303
306 glTranslated(0., 0., -1.);
307
308 fLocked = kFALSE;
309}
310
311////////////////////////////////////////////////////////////////////////////////
312///When TPad::Range for gPad is called, projection
313///must be changed in OpenGL.
314
316{
317 if (fLocked) return;
318
321
322 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
323
325}
326
327////////////////////////////////////////////////////////////////////////////////
328///Locked state of painter means, that
329///GL context can be invalid, so no GL calls
330///can be executed.
331
333{
334 if (fLocked) return;
335
336 glFinish();
337 fLocked = kTRUE;
338}
339
340/*
3412D primitives.
342*/
343
345
346////////////////////////////////////////////////////////////////////////////////
347///Draw line segment.
348
350{
351 if (fLocked) {
352 //GL pad painter can be called in non-standard situation:
353 //not from TPad::Paint, but
354 //from TView3D::ExecuteRotateView. This means in fact,
355 //that TView3D wants to draw itself in a XOR mode, via
356 //gVirtualX.
357 // TODO: only here set line attributes to virtual x
358 if (IsInvertMode())
359 gVirtualX->DrawLineW(fWinContext,
360 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
361 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2));
362
363 return;
364 }
365
367
368 glBegin(GL_LINES);
369 glVertex2d(x1, y1);
370 glVertex2d(x2, y2);
371 glEnd();
372
374 Double_t pointSize = GetAttLine().GetLineWidth();
380 glBegin(GL_POINTS);
381
382 glVertex2d(x1, y1);
383 glVertex2d(x2, y2);
384
385 glEnd();
386 glPointSize(1.f);
387 }
388
389}
390
391////////////////////////////////////////////////////////////////////////////////
392///Draw line segment in NDC coordinates.
393
395{
396 if (fLocked) {
397 // this code used when crosshair cursor is drawn or interactive objects move
398 if (IsInvertMode())
399 gVirtualX->DrawLineW(fWinContext,
400 gPad->UtoAbsPixel(u1), gPad->VtoAbsPixel(v1),
401 gPad->UtoAbsPixel(u2), gPad->VtoAbsPixel(v2));
402 return;
403 }
404
406 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
407 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
408
409 glBegin(GL_LINES);
410 glVertex2d(gPad->GetX1() + u1 * xRange, gPad->GetY1() + v1 * yRange);
411 glVertex2d(gPad->GetX1() + u2 * xRange, gPad->GetY1() + v2 * yRange);
412 glEnd();
413}
414
415////////////////////////////////////////////////////////////////////////////////
416///Draw filled or hollow box.
417
419{
420 if (fLocked) {
421 //GL pad painter can be called in non-standard situation:
422 //not from TPad::Paint, but
423 //from TView3D::ExecuteRotateView. This means in fact,
424 //that TView3D wants to draw itself in a XOR mode, via
425 //gVirtualX.
426 // TODO: only here set line attributes to virtual x
427 if (IsInvertMode())
428 gVirtualX->DrawBoxW(fWinContext,
429 gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
430 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2),
432 return;
433 }
434
436 Double_t xs[] = {x1, x2, x2, x1};
437 Double_t ys[] = {y1, y1, y2, y2};
439 return;
440 }
441
442 if (mode == kHollow) {
444 glBegin(GL_LINE_LOOP);
445 glVertex2d(x1, y1);
446 glVertex2d(x2, y1);
447 glVertex2d(x2, y2);
448 glVertex2d(x1, y2);
449 glEnd();
450 } else {
451 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE, &fGlFillAtt);//Set filling parameters.
452 glRectd(x1, y1, x2, y2);
453 }
454}
455
456////////////////////////////////////////////////////////////////////////////////
457///Draw tesselated polygon (probably, outline only).
458
460{
461 assert(x != nullptr && "DrawFillArea, parameter 'x' is null");
462 assert(y != nullptr && "DrawFillArea, parameter 'y' is null");
463
464 if (fLocked)
465 return;
466
467 if (n < 3) {
468 ::Error("TGLPadPainter::DrawFillArea",
469 "invalid number of points in a polygon");
470 return;
471 }
472
474 return DrawPolygonWithGradient(n, x, y);
475
476 if (fFullyTransparent) {
478 return DrawPolyLine(n, x, y);
479 }
480
482 DrawTesselation(n, x, y);
483}
484
485////////////////////////////////////////////////////////////////////////////////
486///Draw tesselated polygon (never called, probably, since TPad::PaintFillArea for floats
487///is deprecated).
488
490{
491 if (fLocked) return;
492
493 if (fFullyTransparent) {
495 return DrawPolyLine(n, x, y);
496 }
497
498 fVs.resize(n * 3);
499
500 for (Int_t i = 0; i < n; ++i) {
501 fVs[i * 3] = x[i];
502 fVs[i * 3 + 1] = y[i];
503 }
504
506
510
511 for (Int_t i = 0; i < n; ++i)
512 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
513
514
515 gluEndPolygon(t);
516}
517
518////////////////////////////////////////////////////////////////////////////////
519///Draw poly-line in user coordinates.
520
521template<class ValueType>
522void TGLPadPainter::DrawPolyLineHelper(Int_t n, const ValueType *x, const ValueType *y)
523{
524 if (fLocked) {
525 if (IsInvertMode() && (n > 1)) {
526 std::vector<TPoint> xy(n);
527 for (Int_t i = 0; i < n; ++i) {
528 xy[i].fX = (SCoord_t) gPad->XtoAbsPixel(x[i]);
529 xy[i].fY = (SCoord_t) gPad->YtoAbsPixel(y[i]);
530 }
531 gVirtualX->DrawPolyLineW(fWinContext, xy.size(), xy.data());
532 }
533 return;
534 }
535
537
538 glBegin(GL_LINE_STRIP);
539
540 for (Int_t i = 0; i < n; ++i)
541 glVertex2d(x[i], y[i]);
542
543 if (fIsHollowArea) {
544 glVertex2d(x[0], y[0]);
546 }
547 glEnd();
548
550 Double_t pointSize = GetAttLine().GetLineWidth();
556 glBegin(GL_POINTS);
557
558 for (Int_t i = 0; i < n; ++i)
559 glVertex2d(x[i], y[i]);
560
561 glEnd();
562 glPointSize(1.f);
563 }
564}
565
566////////////////////////////////////////////////////////////////////////////////
567/// Draw poly-line in user coordinates.
568
570{
572}
573
574////////////////////////////////////////////////////////////////////////////////
575/// Draw poly-line in user coordinates.
576
578{
580}
581
582////////////////////////////////////////////////////////////////////////////////
583///Poly line in NDC.
584
586{
587 if (fLocked) return;
588
590 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
591 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
592 const Double_t x1 = gPad->GetX1(), y1 = gPad->GetY1();
593
594 glBegin(GL_LINE_STRIP);
595
596 for (Int_t i = 0; i < n; ++i)
597 glVertex2d(x1 + u[i] * xRange, y1 + v[i] * yRange);
598
599 glEnd();
600}
601
602////////////////////////////////////////////////////////////////////////////////
603/// Returns true when invert mode is configured and painter in locked state
604/// Used when non-opaque of objects moving is involved
605
610
611////////////////////////////////////////////////////////////////////////////////
612///Poly-marker drawing
613
614template<class ValueType>
615void TGLPadPainter::DrawPolyMarkerHelper(Int_t n, const ValueType *x, const ValueType *y)
616{
617 std::vector<TPoint> poly(n);
618
619 if (fLocked) {
620 if (IsInvertMode()) {
621 for (Int_t i = 0; i < n; ++i) {
622 poly[i].fX = gPad->XtoAbsPixel(x[i]);
623 poly[i].fY = gPad->YtoAbsPixel(y[i]);
624 }
625 gVirtualX->DrawPolyMarkerW(fWinContext, poly.size(), poly.data());
626 }
627 return;
628 }
629
630 const UInt_t padH = gPad->GetPadHeight();
631
632 for (Int_t i = 0; i < n; ++i) {
633 poly[i].fX = gPad->XtoPixel(x[i]);
634 poly[i].fY = padH - gPad->YtoPixel(y[i]);
635 }
636
639 //
640 glOrtho(0, gPad->GetPadWidth(), 0, gPad->GetPadHeight(), -10., 10.);
641 //
643 //
645
646 Float_t rgba[4] = {};
650
653
655
658 glLineWidth(1.f);
659}
660
661////////////////////////////////////////////////////////////////////////////////
662///Poly-marker.
663
668
669////////////////////////////////////////////////////////////////////////////////
670///Poly-marker.
671
676
677////////////////////////////////////////////////////////////////////////////////
678/// Select specified font/size
679
681{
682 //10 is the first valid font index.
683 //20 is FreeSerifBold, as in TTF.cxx and in TGLFontManager.cxx.
684 //shift - is the shift to access "extended" fonts.
686
687 Int_t fontIndex = TMath::Max(Font_t(10), font);
688 if (fontIndex / 10 + shift > TGLFontManager::GetFontFileArray()->GetEntries())
689 fontIndex = 20 + shift * 10;
690 else
691 fontIndex += shift * 10;
692
693 Int_t textSize = TMath::Max(Int_t(tsize) - 1, 10);
694
696
698}
699
700////////////////////////////////////////////////////////////////////////////////
701/// Helper function to draw text
702
703template<class Char>
705{
707
709 //
710 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
711 //
713
714 Float_t rgba[4] = {};
717
718 SelectGLFont(GetAttText().GetTextFont(), GetAttText().GetTextSizePixels(*gPad));
719
721
722 fF.PreRender();
723
724 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
725 fF.Render(text, gPad->XtoPixel(x), padH - gPad->YtoPixel(y), GetTextAngle(), GetTextMagnitude());
726
727 fF.PostRender();
729
731}
732
733////////////////////////////////////////////////////////////////////////////////
734///Draw text. This operation is especially
735///dangerous if in locked state -
736///ftgl will assert on zero texture size
737///(which is result of bad GL context).
738
740{
741 if (fLocked) return;
742
743 if (GetAttText().GetTextSize() > 0)
745}
746
747////////////////////////////////////////////////////////////////////////////////
748///Draw text. This operation is especially
749///dangerous if in locked state -
750///ftgl will assert on zero texture size
751///(which is result of bad GL context).
752
754{
755 if (fLocked) return;
756
757 if (GetAttText().GetTextSize() > 0)
759}
760
761////////////////////////////////////////////////////////////////////////////////
762///Draw text in NDC. This operation is especially
763///dangerous if in locked state -
764///ftgl will assert on zero texture size
765///(which is result of bad GL context).
766
768{
769 if (fLocked) return;
770
771 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
772 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
773 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
774}
775
776////////////////////////////////////////////////////////////////////////////////
777///Draw text in NDC. This operation is especially
778///dangerous if in locked state -
779///ftgl will assert on zero texture size
780///(which is result of bad GL context).
781
783{
784 if (fLocked) return;
785
786 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
787 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
788 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
789}
790
791////////////////////////////////////////////////////////////////////////////////
792///Save the projection matrix.
793///Attention! GL_PROJECTION will become the current matrix
794///after this call!
795
801
802////////////////////////////////////////////////////////////////////////////////
803///Restore the projection matrix.
804///Attention! GL_PROJECTION will become the current matrix
805///after this call!
806
812
813////////////////////////////////////////////////////////////////////////////////
814///Save the modelview matrix.
815///Attention! GL_MODELVIEW will become the current matrix
816///after this call!
817
823
824////////////////////////////////////////////////////////////////////////////////
825///Restore the modelview matrix.
826///Attention! GL_MODELVIEW will become the current matrix
827///after this call!
828
834
835////////////////////////////////////////////////////////////////////////////////
836///Extract and save the current viewport.
837
842
843////////////////////////////////////////////////////////////////////////////////
844///Restore the saved viewport.
845
847{
848 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
849}
850
851////////////////////////////////////////////////////////////////////////////////
852/// Using TImage save frame-buffer contents as a picture.
853
854void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
855{
856 auto canvas = pad->GetCanvas();
857 if (!canvas)
858 return;
859
860 canvas->Flush();
861
862 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
865 //In case GL_BGRA is not in gl.h (old windows' gl) - comment/uncomment lines.
866 //glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_BGRA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
867 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
868
869 std::unique_ptr<TImage> image(TImage::Create());
870 if (!image.get()) {
871 ::Error("TGLPadPainter::SaveImage", "TImage creation failed");
872 return;
873 }
874
875 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
876 UInt_t *argb = image->GetArgbArray();
877
878 if (!argb) {
879 ::Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
880 return;
881 }
882
883 const Int_t nLines = canvas->GetWh();
884 const Int_t nPixels = canvas->GetWw();
885
886 for (Int_t i = 0; i < nLines; ++i) {
887 Int_t base = (nLines - 1 - i) * nPixels;
888 for (Int_t j = 0; j < nPixels; ++j, ++base) {
889 //Uncomment/comment if you don't have GL_BGRA.
890
891 const UInt_t pix = buff[base];
892 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
893 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
894
895 //argb[i * nPixels + j] = buff[base];
896 argb[i * nPixels + j] = bgra;
897 }
898 }
899
900 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
901}
902
903////////////////////////////////////////////////////////////////////////////////
904
907{
908 if (fLocked)
909 return;
910
911 if (!pixelData) {
912 //I'd prefer an assert.
913 ::Error("TGLPadPainter::DrawPixels", "pixel data is null");
914 return;
915 }
916
917 if (std::numeric_limits<UInt_t>::digits >= 32) {
918 //TASImage uses bit 31 as ...
919 //alpha channel flag! FUUUUUUUUUUUUU ..... !!!
920 CLRBIT(width, 31);
921 CLRBIT(height, 31);
922 }
923
924 if (!width) {
925 //Assert is better.
926 ::Error("TGLPadPainter::DrawPixels", "invalid width");
927 return;
928 }
929
930 if (!height) {
931 //Assert is better.
932 ::Error("TGLPadPainter::DrawPixels", "invalid height");
933 return;
934 }
935
936 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
937 //TASImage passes pixel coordinates in pad's pixmap coordinate space.
938 //While glRasterPosX said to work with 'window' coordinates,
939 //that's a lie :) it does not :)
940
941 const Double_t rasterX = Double_t(dstX) / (pad->GetAbsWNDC() * pad->GetWw()) *
942 (pad->GetX2() - pad->GetX1()) + pad->GetX1();
943
944 const Double_t yRange = pad->GetY2() - pad->GetY1();
945 const Double_t rasterY = yRange - Double_t(dstY + height) / (pad->GetAbsHNDC() * pad->GetWh()) * yRange +
946 pad->GetY1();
947
948 GLdouble oldPos[4] = {};
949 //Save the previous raster pos.
951
953 //Stupid asimage provides us upside-down image.
954 std::vector<unsigned char> upsideDownImage(4 * width * height);
955 const unsigned char *srcLine = pixelData + 4 * width * (height - 1);
956 unsigned char *dstLine = &upsideDownImage[0];
957 for (UInt_t i = 0; i < height; ++i, srcLine -= 4 * width, dstLine += 4 * width)
958 std::copy(srcLine, srcLine + 4 * width, dstLine);
959
960 if (enableBlending) {
963 }
964
966
967 if (enableBlending)
969
970 //Restore raster pos.
972 } else
973 ::Error("TGLPadPainter::DrawPixels", "no pad found to draw");
974}
975
976//Aux. functions - gradient and solid fill of arbitrary area.
977
978////////////////////////////////////////////////////////////////////////////////
979///At the moment I assume both linear and radial gradients will work the same way -
980///using a stencil buffer and some big rectangle(s) to fill with a gradient.
981///Thus I have a 'common' part - the part responsible for a stencil test.
982
984{
985 assert(n > 2 && "DrawPolygonWithGradient, invalid number of points");
986 assert(x != nullptr && "DrawPolygonWithGradient, parameter 'x' is null");
987 assert(y != nullptr && "DrawPolygonWithGradient, parameter 'y' is null");
988
989 auto grad = dynamic_cast<TColorGradient *>(gROOT->GetColor(fGlFillAtt.GetFillColor()));
990 assert(grad != nullptr && "DrawPolygonWithGradient, the current fill color is not a gradient fill");
991
992 if (fLocked)
993 return;
994
995 //Now, some magic!
997
998 //TODO: check that the state is restored back correctly after
999 // we done with a gradient.
1000 //TODO: make sure that we have glDepthMask set to false in general!
1002
1003 glStencilFunc(GL_NEVER, 1, 0xFF);
1004 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);// draw 1s on test fail (always)
1005 //Draw stencil pattern
1006 glStencilMask(0xFF);
1008
1009 //Draw our polygon into the stencil buffer:
1010 DrawTesselation(n, x, y);
1011
1013 glStencilMask(0x00);
1014 //Draw where stencil's value is 0
1015 glStencilFunc(GL_EQUAL, 0, 0xFF);
1016 //Draw only where stencil's value is 1
1017 glStencilFunc(GL_EQUAL, 1, 0xFF);
1018
1019 //At the moment radial gradient is derived from linear - it was convenient
1020 //at some point, but in fact it was a bad idea. And now I have to
1021 //first check radial gradient.
1022 //TODO: TRadialGradient must inherit TColorGradient directly.
1023 const TRadialGradient * const rGrad = dynamic_cast<const TRadialGradient *>(grad);
1024 if (rGrad)
1025 DrawGradient(rGrad, n, x, y);
1026 else {
1027 const TLinearGradient * const lGrad = dynamic_cast<const TLinearGradient *>(grad);
1028 assert(lGrad != nullptr && "DrawPolygonWithGradient, unknown gradient type");
1029 DrawGradient(lGrad, n, x, y);
1030 }
1031}
1032
1033////////////////////////////////////////////////////////////////////////////////
1034
1036 const Double_t *xs, const Double_t *ys)
1037{
1038 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1039 assert(nPoints > 2 && "DrawGradient, invalid number of points");
1040 assert(xs != nullptr && "DrawGradient, parameter 'xs' is null");
1041 assert(ys != nullptr && "DrawGradient, parameter 'ys' is null");
1042
1044 ::Warning("TGLPadPainter::DrawGradient",
1045 "extended radial gradient is not supported");//yet?
1046 return;
1047 }
1048
1049 //TODO: check the polygon's bbox!
1050 const auto &bbox = Rgl::Pad::FindBoundingRect(nPoints, xs, ys);
1051 //
1052 auto center = grad->GetCenter();
1053 auto radius = grad->GetRadius();
1054 //Adjust the center and radius depending on coordinate mode.
1056 radius *= TMath::Max(bbox.fWidth, bbox.fHeight);
1057 center.fX = bbox.fWidth * center.fX + bbox.fXMin;
1058 center.fY = bbox.fHeight * center.fY + bbox.fYMin;
1059 } else {
1060 const auto w = gPad->GetX2() - gPad->GetX1();
1061 const auto h = gPad->GetY2() - gPad->GetY1();
1062
1063 radius *= TMath::Max(w, h);
1064 center.fX *= w;
1065 center.fY *= h;
1066 }
1067 //Now for the gradient fill we switch into pixel coordinates:
1068 const auto pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1069 const auto pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1070 //
1073 //A new ortho projection:
1076 //
1077 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1078 //
1080 center.fX = gPad->XtoPixel(center.fX);
1081 center.fY = pixelH - gPad->YtoPixel(center.fY);
1082
1083 Double_t maxR = 0.;
1084 {
1085 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1086 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1087 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1088 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1089 //Get the longest distance from the center to the bounding box vertices
1090 //(this will be the maximum possible radius):
1091 const Double_t maxDistX = TMath::Max(TMath::Abs(center.fX - xMin),
1092 TMath::Abs(center.fX - xMax));
1093 const Double_t maxDistY = TMath::Max(TMath::Abs(center.fY - yMin),
1094 TMath::Abs(center.fY - yMax));
1096 }
1097
1098 //If gradient 'stops inside the polygon', we use
1099 //the solid fill for the area outside of radial gradient:
1100 const Bool_t solidFillAfter = maxR > radius;
1101 //We emulate a radial gradient using triangles and linear gradient:
1102 //TODO: Can be something smarter? (btw even 100 seems to be enough)
1103 const UInt_t nSlices = 500;
1104
1105 const auto nColors = grad->GetNumberOfSteps();
1106 //+1 - the strip from the last color's position to radius,
1107 //and (probably) + 1 for solidFillAfter.
1108 const auto nCircles = nColors + 1 + solidFillAfter;
1109
1110 //TODO: can locations be outside of [0., 1.] ???
1111 //at the moment I assume the answer is NO, NEVER.
1112 const auto locations = grad->GetColorPositions();
1113 // * 2 below == x,y
1114 std::vector<Double_t> circles(nSlices * nCircles * 2);
1115 const Double_t angle = TMath::TwoPi() / nSlices;
1116
1117 //"Main" circles (for colors at locations[i]).
1118 for (UInt_t i = 0; i < nColors; ++i) {
1119 const auto circle = &circles[i * nSlices * 2];
1120 //TODO: either check locations here or somewhere else.
1121 const auto r = radius * locations[i];
1122 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1123 circle[j] = center.fX + r * TMath::Cos(angle * j);
1124 circle[j + 1] = center.fY + r * TMath::Sin(angle * j);
1125 }
1126 //The "closing" vertices:
1127 circle[(nSlices - 1) * 2] = circle[0];
1128 circle[(nSlices - 1) * 2 + 1] = circle[1];
1129 }
1130
1131 {
1132 //The strip between lastPos and radius:
1133 const auto circle = &circles[nColors * nSlices * 2];
1134 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1135 circle[j] = center.fX + radius * TMath::Cos(angle * j);
1136 circle[j + 1] = center.fY + radius * TMath::Sin(angle * j);
1137 }
1138
1139 circle[(nSlices - 1) * 2] = circle[0];
1140 circle[(nSlices - 1) * 2 + 1] = circle[1];
1141 }
1142
1143 if (solidFillAfter) {
1144 //The strip after the radius:
1145 const auto circle = &circles[(nCircles - 1) * nSlices * 2];
1146 for (UInt_t j = 0, e = nSlices * 2 - 2; j < e; j += 2) {
1147 circle[j] = center.fX + maxR * TMath::Cos(angle * j);
1148 circle[j + 1] = center.fY + maxR * TMath::Sin(angle * j);
1149 }
1150
1151 circle[(nSlices - 1) * 2] = circle[0];
1152 circle[(nSlices - 1) * 2 + 1] = circle[1];
1153 }
1154
1155 //Now we draw:
1156 //1) triangle fan in the center (from center to the locations[1],
1157 // with a solid fill).
1158 //2) quad strips for colors.
1159 //3) additional quad strip from the lastLocation to the radius
1160 //4) additional quad strip (if any) from the radius to maxR.
1161
1162 //RGBA values:
1163 const auto rgba = grad->GetColors();
1164
1166 //TODO?
1168
1169 //Probably a degenerated case. Maybe not.
1172 glVertex2d(center.fX, center.fY);
1173
1174 for (UInt_t i = 0, e = nSlices * 2; i < e; i += 2)
1175 glVertex2dv(&circles[i]);
1176
1177 glEnd();
1178
1179 //No auto for circles, explicit types to have const Double_t * const, not Duble_t * const.
1180 for (UInt_t i = 0; i < nColors - 1; ++i) {
1181 const Double_t * const inner = &circles[i * nSlices * 2];
1182 const auto innerRGBA = rgba + i * 4;
1183 const auto outerRGBA = rgba + (i + 1) * 4;
1184 const Double_t * const outer = &circles[(i + 1) * nSlices * 2];
1185
1187 }
1188
1189 //Probably degenerated strip.
1190 {
1191 const Double_t * const inner = &circles[nSlices * (nColors - 1) * 2];
1192 const auto solidRGBA = rgba + (nColors - 1) * 4;
1193 const Double_t * const outer = &circles[nSlices * nColors * 2];
1194
1196 }
1197
1198 if (solidFillAfter) {
1199 const Double_t * const inner = &circles[nSlices * nColors * 2];
1200 const auto solidRGBA = rgba + (nColors - 1) * 4;
1201 const Double_t * const outer = &circles[nSlices * (nColors + 1) * 2];
1202
1204 }
1205
1208}
1209
1210////////////////////////////////////////////////////////////////////////////////
1211
1213 const Double_t *x, const Double_t *y)
1214{
1215 assert(grad != nullptr && "DrawGradient, parameter 'grad' is null");
1216 assert(n > 2 && "DrawGradient, invalid number of points");
1217 assert(x != nullptr && "DrawGradient, parameter 'x' is null");
1218 assert(y != nullptr && "DrawGradient, parameter 'y' is null");
1219
1220 //Now we fill the whole scene with one big rectangle
1221 //(group of rectangles) with a gradient fill using
1222 //stencil test.
1223
1224 //Find a bounding rect.
1225 const auto &bbox = Rgl::Pad::FindBoundingRect(n, x, y);
1226 //TODO: check the bbox??
1227
1228 //For the gradient fill we switch into the
1229 //pixel coordinates.
1232
1233 //A new ortho projection:
1236
1237 const Double_t pixelW = gPad->GetAbsWNDC() * gPad->GetWw();
1238 const Double_t pixelH = gPad->GetAbsHNDC() * gPad->GetWh();
1239 glOrtho(0., pixelW, 0., pixelH, -10., 10.);
1240
1241 //A new modelview:
1244 //
1245 TColorGradient::Point start = grad->GetStart();
1246 TColorGradient::Point end = grad->GetEnd();
1247
1248 //Change gradient coordinates from 'NDC' to pad coords:
1250 {
1251 const Double_t w = gPad->GetX2() - gPad->GetX1();
1252 const Double_t h = gPad->GetY2() - gPad->GetY1();
1253
1254 start.fX = start.fX * w;
1255 start.fY = start.fY * h;
1256 end.fX = end.fX * w;
1257 end.fY = end.fY * h;
1258 } else {
1259 start.fX = start.fX * bbox.fWidth + bbox.fXMin;
1260 start.fY = start.fY * bbox.fHeight + bbox.fYMin;
1261 end.fX = end.fX * bbox.fWidth + bbox.fXMin;
1262 end.fY = end.fY * bbox.fHeight + bbox.fYMin;
1263 }
1264
1265 //TODO: with a radial fill we'll have to extract the code
1266 // below into the separate function/and have additional function
1267 // for a radial gradient.
1268 //Now from pad to pixels:
1269 start.fX = gPad->XtoPixel(start.fX);
1270 start.fY = pixelH - gPad->YtoPixel(start.fY);
1271 end.fX = gPad->XtoPixel(end.fX);
1272 end.fY = pixelH - gPad->YtoPixel(end.fY);
1273 const Double_t xMin = gPad->XtoPixel(bbox.fXMin);
1274 const Double_t xMax = gPad->XtoPixel(bbox.fXMax);
1275 const Double_t yMin = pixelH - gPad->YtoPixel(bbox.fYMin);
1276 const Double_t yMax = pixelH - gPad->YtoPixel(bbox.fYMax);
1277 //
1278
1279 //TODO: check all calculations!
1280
1281 //Get the longest distance from the start point to the bounding box vertices:
1282 const Double_t maxDistX = TMath::Max(TMath::Abs(start.fX - xMin), TMath::Abs(start.fX - xMax));
1283 const Double_t maxDistY = TMath::Max(TMath::Abs(start.fY - yMin), TMath::Abs(start.fY - yMax));
1284
1285 const Double_t startEndLength = TMath::Sqrt((end.fX - start.fX) * (end.fX - start.fX) +
1286 (end.fY - start.fY) * (end.fY - start.fY));
1289
1290 //Boxes with a gradients to emulate gradient fill with many colors:
1291 const Double_t * const colorPositions = grad->GetColorPositions();
1292 std::vector<Double_t> gradBoxes(grad->GetNumberOfSteps() + 2);
1293 gradBoxes[0] = start.fY - h;
1294 for (unsigned i = 1; i <= grad->GetNumberOfSteps(); ++i)
1295 gradBoxes[i] = startEndLength * colorPositions[i - 1] + start.fY;
1296
1297 gradBoxes[grad->GetNumberOfSteps() + 1] = start.fY + h;
1298
1299 //Rotation angle - gradient's axis:
1300 Double_t angle = TMath::ACos((startEndLength * (end.fY - start.fY)) /
1302 if (end.fX > start.fX)
1303 angle *= -1;
1304
1305 glTranslated(start.fX, start.fY, 0.);
1306 glRotated(angle, 0., 0., 1.);
1307 glTranslated(-start.fX, -start.fY, 0.);
1308 //
1309 const Double_t * const rgba = grad->GetColors();
1310
1311 const unsigned nEdges = gradBoxes.size();
1312 const unsigned nColors = grad->GetNumberOfSteps();
1313 const Double_t xLeft = start.fX - h, xRight = start.fX + h;
1314
1316 //TODO?
1318
1321 rgba + (nColors - 1) * 4, rgba + (nColors - 1) * 4);
1322
1323 for (unsigned i = 1; i < nEdges - 2; ++i)
1325 xRight, rgba + (i - 1) * 4, rgba + i * 4);
1326
1329}
1330
1331////////////////////////////////////////////////////////////////////////////////
1332
1334{
1335 assert(n > 2 && "DrawTesselation, invalid number of points");
1336 assert(x != nullptr && "DrawTesselation, parameter 'x' is null");
1337 assert(y != nullptr && "DrawTesselation, parameter 'y' is null");
1338
1339 //Data for a tesselator:
1340 fVs.resize(n * 3);
1341
1342 for (Int_t i = 0; i < n; ++i) {
1343 fVs[i * 3] = x[i];
1344 fVs[i * 3 + 1] = y[i];
1345 fVs[i * 3 + 2] = 0.;
1346 }
1347
1348 //TODO: A very primitive way to tesselate - check what
1349 //kind of polygons we can really have from TPad/TCanvas.
1351 gluBeginPolygon(t);
1353
1354 for (Int_t i = 0; i < n; ++i)
1355 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
1356
1357 gluEndPolygon(t);
1358}
1359
#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:148
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:792
#define gROOT
Definition TROOT.h:417
#define gPad
#define gVirtualX
Definition TVirtualX.h:377
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.
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)
Int_t CreateDrawable(UInt_t w, UInt_t h) override
Not required at the moment.
void RestoreModelviewMatrix() const
Restore the modelview matrix.
std::vector< Double_t > fVs
Bool_t fIsHollowArea
void SaveProjectionMatrix() const
Save the projection matrix.
void DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2) override
Draw line segment.
Bool_t IsCocoa() const override
Returns true when cocoa backend is used.
void SaveModelviewMatrix() const
Save the modelview matrix.
void RestoreViewport()
Restore the saved viewport.
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition TGLUtil.cxx:1573
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition TGLUtil.cxx:1843
EImageFileTypes
Definition TImage.h:36
static TImage * Create()
Create an image.
Definition TImage.cxx:34
const Point & GetEnd() const
Get end.
const Point & GetStart() const
Get start.
void SetAttFill(const TAttFill &att) override
Set fill attributes.
Color_t GetMarkerColor() const override
const TAttText & GetAttText() const override
Get text attributes.
Short_t GetTextAlign() const override
const TAttMarker & GetAttMarker() const override
Get marker attributes.
Style_t GetMarkerStyle() const override
Font_t GetTextFont() const override
Width_t GetLineWidth() const override
Bool_t fFullyTransparent
if transformed fill attributes fully transparent
void SetAttMarker(const TAttMarker &att) override
Set marker attributes.
void SetAttLine(const TAttLine &att) override
Set line attributes.
Float_t GetTextAngle() const override
TAttFill GetAttFillInternal(Bool_t with_transparency)
Returns fill attributes after modification Checks for special fill styles 4000 .
Color_t GetTextColor() const override
Style_t GetLineStyle() const override
const TAttLine & GetAttLine() const override
Get line attributes.
Float_t GetTextSize() const override
The most important graphics class in the ROOT system.
Definition TPad.h:28
SCoord_t fY
Definition TPoint.h:36
SCoord_t fX
Definition TPoint.h:35
Double_t GetRadius() const
Get radius.
const Point & GetCenter() const
Get center.
EGradientType GetGradientType() const
Get gradient type.
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
BoundingRect< ValueType > FindBoundingRect(Int_t nPoints, const ValueType *xs, const ValueType *ys)
void ExtractRGBA(Color_t colorIndex, Float_t *rgba)
void DrawQuadStripWithRadialGradientFill(unsigned nPoints, const Double_t *inner, const Double_t *innerRGBA, const Double_t *outer, const Double_t *outerRGBA)
TODO: is it possible to use GLdouble to avoid problems with Double_t/GLdouble if they are not the sam...
Definition TGLUtil.cxx:3216
void DrawBoxWithGradientFill(Double_t y1, Double_t y2, Double_t x1, Double_t x2, const Double_t *rgba1, const Double_t *rgba2)
Definition TGLUtil.cxx:3196
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Definition TMath.h: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