Logo ROOT  
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
22Implementation 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 };
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
98void 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
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
184void 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
231namespace {
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
321void 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}
#define GL_TRUE
Definition: GL_glu.h:262
#define GL_LINES
Definition: GL_glu.h:284
#define GL_FALSE
Definition: GL_glu.h:261
unsigned short UShort_t
Definition: RtypesCore.h:36
int Int_t
Definition: RtypesCore.h:41
unsigned int UInt_t
Definition: RtypesCore.h:42
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
Int_t Compare(const void *item1, const void *item2)
The color creation and management class.
Definition: TColor.h:19
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition: TColor.h:51
Implementation of a box around a histogram/function for plot-painters.
Definition: TGLPlotBox.h:26
const TColor * fFrameColor
Definition: TGLPlotBox.h:28
Int_t FindFrontPoint() const
Convert 3d points into window coordinate system and find the nearest.
Definition: TGLPlotBox.cxx:245
void DrawFront() const
Definition: TGLPlotBox.cxx:163
virtual ~TGLPlotBox()
Empty dtor to suppress g++ warnings.
Definition: TGLPlotBox.cxx:92
Int_t fFrontPoint
Definition: TGLPlotBox.h:38
static const Int_t fgFrontPairs[][2]
Definition: TGLPlotBox.h:76
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
TGLVertex3 f2DBox[8]
Definition: TGLPlotBox.h:36
TGLVertex3 f2DBoxU[8]
Definition: TGLPlotBox.h:37
const TGLVertex3 * Get3DBox() const
Get 3D box.
Definition: TGLPlotBox.cxx:303
static const Int_t fgFramePlanes[][4]
Definition: TGLPlotBox.h:74
const TGLVertex3 * Get2DBox() const
Get 2D box.
Definition: TGLPlotBox.cxx:312
Double_t fRangeXU
Definition: TGLPlotBox.h:41
Bool_t fDrawFront
Definition: TGLPlotBox.h:46
const Bool_t fXOYSelectable
Definition: TGLPlotBox.h:29
TGLPlotBox(Bool_t xoySelectable, Bool_t xozSelectable, Bool_t yozSelectable)
Constructor.
Definition: TGLPlotBox.cxx:62
Double_t fRangeYU
Definition: TGLPlotBox.h:42
static const Int_t fgBackPairs[][2]
Definition: TGLPlotBox.h:75
Double_t fRangeZU
Definition: TGLPlotBox.h:43
void DrawBack(Int_t selectedPart, Bool_t selectionPass, const std::vector< Double_t > &zLevels, Bool_t highColor) const
Definition: TGLPlotBox.cxx:98
static const Double_t fgNormals[][3]
Definition: TGLPlotBox.h:77
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
void DrawBackPlane(Int_t plane, Bool_t selectionPass, const std::vector< Double_t > &zLevels) const
Draw back plane with number 'plane'.
Definition: TGLPlotBox.cxx:321
void SetFrameColor(const TColor *color)
Back box color.
Definition: TGLPlotBox.cxx:226
Bool_t fDrawBack
Definition: TGLPlotBox.h:45
Bool_t fSelectablePairs[4][2]
Definition: TGLPlotBox.h:33
TGLVertex3 f3DBox[8]
Definition: TGLPlotBox.h:35
Int_t GetFrontPoint() const
The nearest point.
Definition: TGLPlotBox.cxx:294
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition: TGLUtil.cxx:1577
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition: TGLUtil.cxx:1847
3 component (x/y/z) vector class.
Definition: TGLUtil.h:247
3 component (x/y/z) vertex class.
Definition: TGLUtil.h:83
Double_t X() const
Definition: TGLUtil.h:118
Double_t Z() const
Definition: TGLUtil.h:122
void Set(Double_t x, Double_t y, Double_t z)
Definition: TGLUtil.h:209
Double_t Y() const
Definition: TGLUtil.h:120
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
void DrawQuadFilled(const TGLVertex3 &v0, const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVector3 &normal)
Draw quad face.
Definition: TGLUtil.cxx:2954
const Float_t gNullEmission[]
Definition: TGLUtil.cxx:2848
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2892
const Float_t gRedEmission[]
Definition: TGLUtil.cxx:2842
std::pair< Double_t, Double_t > Range_t
Definition: TGLUtil.h:1194
const Float_t gGreenEmission[]
Definition: TGLUtil.cxx:2843
void DrawQuadOutline(const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVertex3 &v4)
Draw quad outline.
Definition: TGLUtil.cxx:2940