Logo ROOT   6.12/07
Reference Guide
TGLPlotBox.cxx
Go to the documentation of this file.
1 // @(#)root/gl:$Id$
2 // Author: Timur Pocheptsov 31/08/2006
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2006, 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 "TGLPlotBox.h"
13 
14 #include "TColor.h"
15 #include "TGLIncludes.h"
16 
17 #include <algorithm>
18 
19 
20 /** \class TGLPlotBox
21 \ingroup opengl
22 Implementation of a box around a histogram/function for plot-painters.
23 */
24 
26 
28  {
29  {0, 4, 5, 1},
30  {1, 5, 6, 2},
31  {2, 6, 7, 3},
32  {0, 3, 7, 4},
33  {0, 1, 2, 3}
34  };
36  {
37  { 0., 1., 0.},
38  {-1., 0., 0.},
39  { 0.,-1., 0.},
40  { 1., 0., 0.},
41  { 0., 0., 1.}
42  };
43 const Int_t TGLPlotBox::fgBackPairs[][2] =
44  {
45  {2, 1},
46  {3, 2},
47  {0, 3},
48  {1, 0}
49  };
50 
52  {
53  {3, 0},
54  {0, 1},
55  {1, 2},
56  {2, 3}
57  };
58 ////////////////////////////////////////////////////////////////////////////////
59 /// Constructor.
60 ///Front point is 0.
61 
63  : fFrameColor(0),
64  fXOYSelectable(xoy),
65  fXOZSelectable(xoz),
66  fYOZSelectable(yoz),
67  fSelectablePairs(),
68  fFrontPoint(0),
69  fRangeXU(1.),
70  fRangeYU(1.),
71  fRangeZU(1.),
72  fDrawBack(kTRUE),
73  fDrawFront(kTRUE)
74 {
75  fSelectablePairs[0][0] = xoz;
76  fSelectablePairs[0][1] = yoz;
77  //Front point is 1.
78  fSelectablePairs[1][0] = yoz;
79  fSelectablePairs[1][1] = xoz;
80  //Front point is 2.
81  fSelectablePairs[2][0] = xoz;
82  fSelectablePairs[2][1] = yoz;
83  //Front point is 3.
84  fSelectablePairs[3][0] = yoz;
85  fSelectablePairs[3][1] = xoz;
86 }
87 
88 
89 ////////////////////////////////////////////////////////////////////////////////
90 /// Empty dtor to suppress g++ warnings.
91 
93 {
94 }
95 
96 ////////////////////////////////////////////////////////////////////////////////
97 
98 void TGLPlotBox::DrawBack(Int_t selected, Bool_t selectionPass, const std::vector<Double_t> &zLevels,
99  Bool_t highColor)const
100 {
101  using namespace Rgl;
102  TGLDisableGuard depthTest(GL_DEPTH_TEST); //[0-0]
103  glDepthMask(GL_FALSE);//[1
104 
105  if (!selectionPass) {
106  glEnable(GL_BLEND);//[2
107  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
108  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
109  glEnable(GL_LINE_SMOOTH);//[3
110  }
111 
112  //Back planes are partially transparent to make their color smoother.
113  Float_t backColor[] = {0.9f, 0.9f, 0.9f, 0.85f};
114  if (fFrameColor)
115  fFrameColor->GetRGB(backColor[0], backColor[1], backColor[2]);
116 
117  if (!selectionPass) {
118  glMaterialfv(GL_FRONT, GL_DIFFUSE, backColor);
119  if (selected == 1) {
121  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
122  :
123  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
124  }
125  } else
126  ObjectIDToColor(1, highColor);//Bottom plane, encoded as 1 in a selection buffer.
127 
128  DrawQuadFilled(f3DBox[0], f3DBox[1], f3DBox[2], f3DBox[3], TGLVector3(0., 0., 1.));
129 
130  if (!selectionPass) {
131  if (selected == 1)
132  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
133  else if (selected == 2)
134  fSelectablePairs[fFrontPoint][0] ? glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
135  : glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
136  } else
137  ObjectIDToColor(2, highColor);//Left plane, encoded as 2 in a selection buffer.
138 
139  DrawBackPlane(fgBackPairs[fFrontPoint][0], selectionPass, zLevels);
140 
141  if (!selectionPass) {
142  if (selected == 2)
143  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
144  else if (selected == 3)
145  fSelectablePairs[fFrontPoint][1] ? glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
146  : glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
147  } else
148  ObjectIDToColor(3, highColor); //Right plane, encoded as 3 in a selection buffer.
149 
150  DrawBackPlane(fgBackPairs[fFrontPoint][1], selectionPass, zLevels);
151 
152  glDepthMask(GL_TRUE);//1]
153  if (!selectionPass) {
154  if (selected == 3)
155  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
156  glDisable(GL_BLEND);//2]
157  glDisable(GL_LINE_SMOOTH);//3]
158  }
159 }
160 
161 ////////////////////////////////////////////////////////////////////////////////
162 
164 {
165  using namespace Rgl;
166 
167  const TGLDisableGuard lightGuard(GL_LIGHTING);
168 // const TGLEnableGuard blend(GL_BLEND);
169 // const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
170 
171  // glColor4d(0., 0., 0., 0.8);
172  glColor3d(0., 0., 0.);
173 
174  const Int_t *vertInd = fgFramePlanes[fgFrontPairs[fFrontPoint][0]];
175  DrawQuadOutline(f3DBox[vertInd[0]], f3DBox[vertInd[1]], f3DBox[vertInd[2]], f3DBox[vertInd[3]]);
176 
177  vertInd = fgFramePlanes[fgFrontPairs[fFrontPoint][1]];
178  DrawQuadOutline(f3DBox[vertInd[0]], f3DBox[vertInd[1]], f3DBox[vertInd[2]], f3DBox[vertInd[3]]);
179 }
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 /// Draw back box for a plot.
183 
184 void TGLPlotBox::DrawBox(Int_t selected, Bool_t selectionPass, const std::vector<Double_t> &zLevels,
185  Bool_t highColor)const
186 {
187  if (fDrawBack)
188  DrawBack(selected, selectionPass, zLevels, highColor);
189 
190  if (fDrawFront && !selectionPass)
191  DrawFront();
192 }
193 
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 /// Set up a frame box.
197 
199 {
200  f3DBox[0].Set(x.first, y.first, z.first);
201  f3DBox[1].Set(x.second, y.first, z.first);
202  f3DBox[2].Set(x.second, y.second, z.first);
203  f3DBox[3].Set(x.first, y.second, z.first);
204  f3DBox[4].Set(x.first, y.first, z.second);
205  f3DBox[5].Set(x.second, y.first, z.second);
206  f3DBox[6].Set(x.second, y.second, z.second);
207  f3DBox[7].Set(x.first, y.second, z.second);
208 }
209 
210 ////////////////////////////////////////////////////////////////////////////////
211 /// Set up a frame box.
212 
214  const Rgl::Range_t &z, Double_t zr)
215 {
216  fRangeXU = xr;
217  fRangeYU = yr;
218  fRangeZU = zr;
219 
220  SetPlotBox(x, y, z);
221 }
222 
223 ////////////////////////////////////////////////////////////////////////////////
224 /// Back box color.
225 
227 {
228  fFrameColor = color;
229 }
230 
231 namespace {
232 
233  bool Compare(const TGLVertex3 &v1, const TGLVertex3 &v2)
234  {
235  return v1.Z() < v2.Z();
236  }
237 
238 }
239 
240 
241 ////////////////////////////////////////////////////////////////////////////////
242 /// Convert 3d points into window coordinate system
243 /// and find the nearest.
244 
246 {
247  Double_t mvMatrix[16] = {0.};
248  glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix);
249  Double_t prMatrix[16] = {0.};
250  glGetDoublev(GL_PROJECTION_MATRIX, prMatrix);
251  Int_t viewport[4] = {0};
252  glGetIntegerv(GL_VIEWPORT, viewport);
253 
254  const Double_t zMin = f3DBox[0].Z();
255  const Double_t zMax = f3DBox[4].Z();
256 
257  const Double_t uBox[][2] = {{-fRangeXU / 2., -fRangeYU / 2.},
258  { fRangeXU / 2., -fRangeYU / 2.},
259  { fRangeXU / 2., fRangeYU / 2.},
260  {-fRangeXU / 2., fRangeYU / 2.}};
261 
262  for (Int_t i = 0; i < 4; ++i) {
263  gluProject(f3DBox[i].X(), f3DBox[i].Y(), zMin, mvMatrix, prMatrix, viewport,
264  &f2DBox[i].X(), &f2DBox[i].Y(), &f2DBox[i].Z());
265  gluProject(f3DBox[i].X(), f3DBox[i].Y(), zMax, mvMatrix, prMatrix, viewport,
266  &f2DBox[i + 4].X(), &f2DBox[i + 4].Y(), &f2DBox[i + 4].Z());
267 
268  gluProject(uBox[i][0], uBox[i][1], -0.5, mvMatrix, prMatrix, viewport,
269  &f2DBoxU[i].X(), &f2DBoxU[i].Y(), &f2DBoxU[i].Z());
270  gluProject(uBox[i][0], uBox[i][1], 0.5, mvMatrix, prMatrix, viewport,
271  &f2DBoxU[i + 4].X(), &f2DBoxU[i + 4].Y(), &f2DBoxU[i + 4].Z());
272  }
273 
274  //2D bbox must be in a canvas space, this can be affected by scaling
275  //on retina displays.
278  if (scale) {
279  for (Int_t i = 0; i < 8; ++i) {
280  //downscale:
281  f2DBoxU[i].X() /= scale;
282  f2DBoxU[i].Y() /= scale;
283  }
284  }
285 
286  //return fFrontPoint = std::min_element(f2DBox, f2DBox + 4, Compare) - f2DBox;
287  return fFrontPoint = std::min_element(f2DBoxU, f2DBoxU + 4, Compare) - f2DBoxU;
288 }
289 
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// The nearest point.
293 
295 {
296  return fFrontPoint;
297 }
298 
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 /// Get 3D box.
302 
304 {
305  return f3DBox;
306 }
307 
308 
309 ////////////////////////////////////////////////////////////////////////////////
310 /// Get 2D box.
311 
313 {
314  return f2DBoxU;
315 }
316 
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 ///Draw back plane with number 'plane'
320 
321 void TGLPlotBox::DrawBackPlane(Int_t plane, Bool_t selectionPass,
322  const std::vector<Double_t> &zLevels)const
323 {
324  using namespace Rgl;
325  const Int_t *vertInd = fgFramePlanes[plane];
326  DrawQuadFilled(f3DBox[vertInd[0]], f3DBox[vertInd[1]], f3DBox[vertInd[2]],
327  f3DBox[vertInd[3]], fgNormals[plane]);
328  //Antialias back plane outline.
329  if (!selectionPass) {
330  const TGLDisableGuard lightGuard(GL_LIGHTING);
331  glColor3d(0., 0., 0.);
332  DrawQuadOutline(f3DBox[vertInd[0]], f3DBox[vertInd[1]],
333  f3DBox[vertInd[2]], f3DBox[vertInd[3]]);
334  //draw grid.
335  const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);//[1-1]
336  const UShort_t stipple = 0x5555;
337  glLineStipple(1, stipple);
338 
339  Double_t lineCaps[][4] =
340  {
341  {f3DBox[1].X(), f3DBox[0].Y(), f3DBox[0].X(), f3DBox[0].Y()},
342  {f3DBox[1].X(), f3DBox[0].Y(), f3DBox[1].X(), f3DBox[2].Y()},
343  {f3DBox[1].X(), f3DBox[2].Y(), f3DBox[0].X(), f3DBox[3].Y()},
344  {f3DBox[0].X(), f3DBox[3].Y(), f3DBox[0].X(), f3DBox[0].Y()}
345  };
346 
347  for (UInt_t i = 0; i < zLevels.size(); ++i) {
348  glBegin(GL_LINES);
349  glVertex3d(lineCaps[plane][0], lineCaps[plane][1], zLevels[i]);
350  glVertex3d(lineCaps[plane][2], lineCaps[plane][3], zLevels[i]);
351  glEnd();
352  }
353 
354  }
355 }
Int_t GetFrontPoint() const
The nearest point.
Definition: TGLPlotBox.cxx:294
const TColor * fFrameColor
Definition: TGLPlotBox.h:28
TGLVertex3 f2DBoxU[8]
Definition: TGLPlotBox.h:37
void DrawQuadFilled(const TGLVertex3 &v0, const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVector3 &normal)
Draw quad face.
Definition: TGLUtil.cxx:2920
const Float_t gNullEmission[]
Definition: TGLUtil.cxx:2814
float Float_t
Definition: RtypesCore.h:53
std::pair< Double_t, Double_t > Range_t
Definition: TGLUtil.h:1193
unsigned short UShort_t
Definition: RtypesCore.h:36
void DrawBack(Int_t selectedPart, Bool_t selectionPass, const std::vector< Double_t > &zLevels, Bool_t highColor) const
Definition: TGLPlotBox.cxx:98
const TGLVertex3 * Get3DBox() const
Get 3D box.
Definition: TGLPlotBox.cxx:303
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition: TGLUtil.cxx:1813
const Bool_t fXOYSelectable
Definition: TGLPlotBox.h:29
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Bool_t fDrawBack
Definition: TGLPlotBox.h:45
void Set(Double_t x, Double_t y, Double_t z)
Definition: TGLUtil.h:209
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition: TColor.h:50
void DrawQuadOutline(const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVertex3 &v4)
Draw quad outline.
Definition: TGLUtil.cxx:2906
TGLVertex3 f2DBox[8]
Definition: TGLPlotBox.h:36
Double_t x[n]
Definition: legend1.C:17
3 component (x/y/z) vertex class.
Definition: TGLUtil.h:82
static const Double_t fgNormals[][3]
Definition: TGLPlotBox.h:77
void DrawBackPlane(Int_t plane, Bool_t selectionPass, const std::vector< Double_t > &zLevels) const
Draw back plane with number &#39;plane&#39;.
Definition: TGLPlotBox.cxx:321
Bool_t fDrawFront
Definition: TGLPlotBox.h:46
static const Int_t fgBackPairs[][2]
Definition: TGLPlotBox.h:75
3 component (x/y/z) vector class.
Definition: TGLUtil.h:246
Implementation of a box around a histogram/function for plot-painters.
Definition: TGLPlotBox.h:26
Int_t fFrontPoint
Definition: TGLPlotBox.h:38
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2858
TGLPlotBox(Bool_t xoySelectable, Bool_t xozSelectable, Bool_t yozSelectable)
Constructor.
Definition: TGLPlotBox.cxx:62
TGLVertex3 f3DBox[8]
Definition: TGLPlotBox.h:35
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition: TGLUtil.cxx:1543
const Float_t gGreenEmission[]
Definition: TGLUtil.cxx:2809
const Float_t gRedEmission[]
Definition: TGLUtil.cxx:2808
static const Int_t fgFrontPairs[][2]
Definition: TGLPlotBox.h:76
unsigned int UInt_t
Definition: RtypesCore.h:42
Int_t FindFrontPoint() const
Convert 3d points into window coordinate system and find the nearest.
Definition: TGLPlotBox.cxx:245
Double_t fRangeYU
Definition: TGLPlotBox.h:42
Bool_t fSelectablePairs[4][2]
Definition: TGLPlotBox.h:33
Double_t fRangeXU
Definition: TGLPlotBox.h:41
void DrawBox(Int_t selectedPart, Bool_t selectionPass, const std::vector< Double_t > &zLevels, Bool_t highColor) const
Draw back box for a plot.
Definition: TGLPlotBox.cxx:184
static const Int_t fgFramePlanes[][4]
Definition: TGLPlotBox.h:74
Double_t Z() const
Definition: TGLUtil.h:122
#define ClassImp(name)
Definition: Rtypes.h:359
double Double_t
Definition: RtypesCore.h:55
void SetFrameColor(const TColor *color)
Back box color.
Definition: TGLPlotBox.cxx:226
Double_t y[n]
Definition: legend1.C:17
The color creation and management class.
Definition: TColor.h:19
virtual ~TGLPlotBox()
Empty dtor to suppress g++ warnings.
Definition: TGLPlotBox.cxx:92
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
void DrawFront() const
Definition: TGLPlotBox.cxx:163
Int_t Compare(const void *item1, const void *item2)
Double_t fRangeZU
Definition: TGLPlotBox.h:43
void SetPlotBox(const Rgl::Range_t &xRange, const Rgl::Range_t &yRange, const Rgl::Range_t &zRange)
Set up a frame box.
Definition: TGLPlotBox.cxx:198
Double_t Y() const
Definition: TGLUtil.h:120
const Bool_t kTRUE
Definition: RtypesCore.h:87
const TGLVertex3 * Get2DBox() const
Get 2D box.
Definition: TGLPlotBox.cxx:312
Double_t X() const
Definition: TGLUtil.h:118