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