Geant4  10.02.p01
G4OpenGLStoredViewer.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4OpenGLStoredViewer.cc 91686 2015-07-31 09:40:08Z gcosmo $
28 //
29 //
30 // Andrew Walkden 7th February 1997
31 // Class G4OpenGLStoredViewer : Encapsulates the `storedness' of
32 // an OpenGL view, for inheritance by
33 // derived (X, Xm...) classes.
34 
35 #ifdef G4VIS_BUILD_OPENGL_DRIVER
36 
37 #include "G4OpenGLStoredViewer.hh"
38 
39 #include "G4PhysicalConstants.hh"
41 #include "G4Text.hh"
42 #include "G4Circle.hh"
43 #include "G4UnitsTable.hh"
44 #include "G4Scene.hh"
45 #include "G4OpenGLTransform3D.hh"
46 
47 G4OpenGLStoredViewer::G4OpenGLStoredViewer
48 (G4OpenGLStoredSceneHandler& sceneHandler):
49 G4VViewer (sceneHandler, -1),
50 G4OpenGLViewer (sceneHandler),
51 fG4OpenGLStoredSceneHandler (sceneHandler),
52 fDepthTestEnable(true)
53 {
54  fLastVP = fDefaultVP; // Not sure if this gets executed before or
55  // after G4VViewer::G4VViewer!! Doesn't matter much.
56 }
57 
58 G4OpenGLStoredViewer::~G4OpenGLStoredViewer () {}
59 
60 void G4OpenGLStoredViewer::KernelVisitDecision () {
61 
62  // If there's a significant difference with the last view parameters
63  // of either the scene handler or this viewer, trigger a rebuild.
64 
65  if (!fG4OpenGLStoredSceneHandler.fTopPODL ||
66  CompareForKernelVisit(fLastVP)) {
67  NeedKernelVisit ();
68  }
69  fLastVP = fVP;
70 }
71 
72 G4bool G4OpenGLStoredViewer::CompareForKernelVisit(G4ViewParameters& lastVP) {
73 
74  if (
75  (lastVP.GetDrawingStyle () != fVP.GetDrawingStyle ()) ||
76  (lastVP.IsAuxEdgeVisible () != fVP.IsAuxEdgeVisible ()) ||
77  (lastVP.IsCulling () != fVP.IsCulling ()) ||
78  (lastVP.IsCullingInvisible () != fVP.IsCullingInvisible ()) ||
79  (lastVP.IsDensityCulling () != fVP.IsDensityCulling ()) ||
80  (lastVP.IsCullingCovered () != fVP.IsCullingCovered ()) ||
81  (lastVP.IsSection () != fVP.IsSection ()) ||
82  // Section (DCUT) implemented locally. But still need to visit
83  // kernel if status changes so that back plane culling can be
84  // switched.
85  (lastVP.IsCutaway () != fVP.IsCutaway ()) ||
86  // Cutaways implemented locally. But still need to visit kernel
87  // if status changes so that back plane culling can be switched.
88  (lastVP.IsExplode () != fVP.IsExplode ()) ||
89  (lastVP.GetNoOfSides () != fVP.GetNoOfSides ()) ||
90  (lastVP.GetDefaultVisAttributes()->GetColour() !=
91  fVP.GetDefaultVisAttributes()->GetColour()) ||
93  fVP.GetDefaultTextVisAttributes()->GetColour()) ||
94  (lastVP.GetBackgroundColour ()!= fVP.GetBackgroundColour ())||
95  (lastVP.IsPicking () != fVP.IsPicking ()) ||
96  (lastVP.GetVisAttributesModifiers().size() !=
97  fVP.GetVisAttributesModifiers().size())
98  )
99  return true;
100 
101  if (lastVP.IsDensityCulling () &&
102  (lastVP.GetVisibleDensity () != fVP.GetVisibleDensity ()))
103  return true;
104 
105  /**************************************************************
106  Section (DCUT) implemented locally. No need to visit kernel if
107  section plane itself changes.
108  if (lastVP.IsSection () &&
109  (lastVP.GetSectionPlane () != fVP.GetSectionPlane ()))
110  return true;
111  ***************************************************************/
112 
113  /**************************************************************
114  Cutaways implemented locally. No need to visit kernel if cutaway
115  planes themselves change.
116  if (lastVP.IsCutaway ()) {
117  if (lastVP.GetCutawayPlanes ().size () !=
118  fVP.GetCutawayPlanes ().size ()) return true;
119  for (size_t i = 0; i < lastVP.GetCutawayPlanes().size(); ++i)
120  if (lastVP.GetCutawayPlanes()[i] != fVP.GetCutawayPlanes()[i])
121  return true;
122  }
123  ***************************************************************/
124 
125  if (lastVP.IsExplode () &&
126  (lastVP.GetExplodeFactor () != fVP.GetExplodeFactor ()))
127  return true;
128 
129  return false;
130 }
131 
132 void G4OpenGLStoredViewer::DrawDisplayLists () {
133 
134  const G4Planes& cutaways = fVP.GetCutawayPlanes();
135  G4bool cutawayUnion = fVP.IsCutaway() &&
136  fVP.GetCutawayMode() == G4ViewParameters::cutawayUnion;
137  const size_t nCutaways = cutawayUnion? cutaways.size(): 1;
138  G4int iPass = 1;
139  G4bool secondPassForTransparencyRequested = false;
140  G4bool thirdPassForNonHiddenMarkersRequested = false;
141  fDepthTestEnable = true;
142  glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);
143  fOldDisplayListColor = G4Colour();
144  do {
145  for (size_t iCutaway = 0; iCutaway < nCutaways; ++iCutaway) {
146 
147  if (cutawayUnion) {
148  double a[4];
149  a[0] = cutaways[iCutaway].a();
150  a[1] = cutaways[iCutaway].b();
151  a[2] = cutaways[iCutaway].c();
152  a[3] = cutaways[iCutaway].d();
153  glClipPlane (GL_CLIP_PLANE2, a);
154  glEnable (GL_CLIP_PLANE2);
155  }
156 
157  G4bool isPicking = fVP.IsPicking();
158 
159  for (size_t iPO = 0;
160  iPO < fG4OpenGLStoredSceneHandler.fPOList.size(); ++iPO) {
161  if (POSelected(iPO)) {
162  G4OpenGLStoredSceneHandler::PO& po =
163  fG4OpenGLStoredSceneHandler.fPOList[iPO];
164  G4Colour c = po.fColour;
165  DisplayTimePOColourModification(c,iPO);
166  const G4bool isTransparent = c.GetAlpha() < 1.;
167  if ( iPass == 1) {
168  if (isTransparent && transparency_enabled) {
169  secondPassForTransparencyRequested = true;
170  continue;
171  }
172  if (po.fMarkerOrPolyline && fVP.IsMarkerNotHidden()) {
173  thirdPassForNonHiddenMarkersRequested = true;
174  continue;
175  }
176  } else if (iPass == 2) { // Second pass for transparency.
177  if (!isTransparent) {
178  continue;
179  }
180  } else { // Third pass for non-hidden markers
181  if (!po.fMarkerOrPolyline) {
182  continue;
183  }
184  }
185  if (isPicking) glLoadName(po.fPickName);
186  if ((iPO == 0) || (c != fOldDisplayListColor)) {
187  fOldDisplayListColor = c;
188  if (transparency_enabled) {
189  glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
190  } else {
191  glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
192  }
193  }
194  if (po.fMarkerOrPolyline && fVP.IsMarkerNotHidden()) {
195  if (fDepthTestEnable !=false) {
196  glDisable (GL_DEPTH_TEST);
197  fDepthTestEnable = false;
198  }
199  } else {
200  if (fDepthTestEnable !=true) {
201  glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);
202  fDepthTestEnable = true;
203  }
204  }
205  if (po.fpG4TextPlus) {
206  if (po.fpG4TextPlus->fProcessing2D) {
207  glMatrixMode (GL_PROJECTION);
208  glPushMatrix();
209  glLoadIdentity();
210  g4GlOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
211  glMatrixMode (GL_MODELVIEW);
212  glPushMatrix();
213  glLoadIdentity();
214  G4OpenGLTransform3D oglt (po.fTransform);
215  glMultMatrixd (oglt.GetGLMatrix ());
216  fOpenGLSceneHandler.G4OpenGLSceneHandler::AddPrimitive
217  (po.fpG4TextPlus->fG4Text);
218  } else {
219  glPushMatrix();
220  G4OpenGLTransform3D oglt (po.fTransform);
221  glMultMatrixd (oglt.GetGLMatrix ());
222  fOpenGLSceneHandler.G4OpenGLSceneHandler::AddPrimitive
223  (po.fpG4TextPlus->fG4Text);
224  glPopMatrix();
225  }
226 
227  if (po.fpG4TextPlus->fProcessing2D) {
228  glMatrixMode (GL_PROJECTION);
229  glPopMatrix();
230  glMatrixMode (GL_MODELVIEW);
231  glPopMatrix();
232  }
233  } else {
234  glPushMatrix();
235  G4OpenGLTransform3D oglt (po.fTransform);
236  glMultMatrixd (oglt.GetGLMatrix ());
237  glCallList (po.fDisplayListId);
238  glPopMatrix();
239  }
240  }
241  }
242 
243  G4Transform3D lastMatrixTransform;
244  G4bool first = true;
245 
246  for (size_t iTO = 0;
247  iTO < fG4OpenGLStoredSceneHandler.fTOList.size(); ++iTO) {
248  if (TOSelected(iTO)) {
249  G4OpenGLStoredSceneHandler::TO& to =
250  fG4OpenGLStoredSceneHandler.fTOList[iTO];
251  const G4Colour& c = to.fColour;
252  const G4bool isTransparent = c.GetAlpha() < 1.;
253  if ( iPass == 1) {
254  if (isTransparent && transparency_enabled) {
255  secondPassForTransparencyRequested = true;
256  continue;
257  }
258  if (to.fMarkerOrPolyline && fVP.IsMarkerNotHidden()) {
259  thirdPassForNonHiddenMarkersRequested = true;
260  continue;
261  }
262  } else if (iPass == 2) { // Second pass for transparency.
263  if (!isTransparent) {
264  continue;
265  }
266  } else { // Third pass for non-hidden markers
267  if (!to.fMarkerOrPolyline) {
268  continue;
269  }
270  }
271  if (to.fMarkerOrPolyline && fVP.IsMarkerNotHidden()) {
272  if (fDepthTestEnable !=false) {
273  glDisable (GL_DEPTH_TEST);
274  fDepthTestEnable = false;
275  }
276  } else {
277  if (fDepthTestEnable !=true) {
278  glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);
279  fDepthTestEnable = true;
280  }
281  }
282  if (to.fEndTime >= fStartTime && to.fStartTime <= fEndTime) {
283  if (fVP.IsPicking()) glLoadName(to.fPickName);
284  if (to.fpG4TextPlus) {
285  if (to.fpG4TextPlus->fProcessing2D) {
286  glMatrixMode (GL_PROJECTION);
287  glPushMatrix();
288  glLoadIdentity();
289  g4GlOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
290  glMatrixMode (GL_MODELVIEW);
291  glPushMatrix();
292  glLoadIdentity();
293  }
294  G4OpenGLTransform3D oglt (to.fTransform);
295  glMultMatrixd (oglt.GetGLMatrix ());
296  if (transparency_enabled) {
297  glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
298  } else {
299  glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
300  }
301  fOpenGLSceneHandler.G4OpenGLSceneHandler::AddPrimitive
302  (to.fpG4TextPlus->fG4Text);
303  if (to.fpG4TextPlus->fProcessing2D) {
304  glMatrixMode (GL_PROJECTION);
305  glPopMatrix();
306  glMatrixMode (GL_MODELVIEW);
307  glPopMatrix();
308  }
309  } else {
310  if (to.fTransform != lastMatrixTransform) {
311  if (! first) {
312  glPopMatrix();
313  }
314  first = false;
315  glPushMatrix();
316  G4OpenGLTransform3D oglt (to.fTransform);
317  glMultMatrixd (oglt.GetGLMatrix ());
318  }
319  const G4Colour& cc = to.fColour;
320  if (fFadeFactor > 0. && to.fEndTime < fEndTime) {
321  // Brightness scaling factor
322  G4double bsf = 1. - fFadeFactor *
323  ((fEndTime - to.fEndTime) / (fEndTime - fStartTime));
324  const G4Colour& bg = fVP.GetBackgroundColour();
325  if (transparency_enabled) {
326  glColor4d
327  (bsf * cc.GetRed() + (1. - bsf) * bg.GetRed(),
328  bsf * cc.GetGreen() + (1. - bsf) * bg.GetGreen(),
329  bsf * cc.GetBlue() + (1. - bsf) * bg.GetBlue(),
330  bsf * cc.GetAlpha() + (1. - bsf) * bg.GetAlpha());
331  } else {
332  glColor3d
333  (bsf * cc.GetRed() + (1. - bsf) * bg.GetRed(),
334  bsf * cc.GetGreen() + (1. - bsf) * bg.GetGreen(),
335  bsf * cc.GetBlue() + (1. - bsf) * bg.GetBlue());
336  }
337  } else {
338  if (transparency_enabled) {
339  glColor4d(cc.GetRed(),cc.GetGreen(),cc.GetBlue(),cc.GetAlpha());
340  } else {
341  glColor3d(cc.GetRed(),cc.GetGreen(),cc.GetBlue());
342  }
343  }
344  glCallList (to.fDisplayListId);
345  }
346  if (to.fTransform != lastMatrixTransform) {
347  lastMatrixTransform = to.fTransform;
348  }
349  }
350  }
351  }
352  if (! first) {
353  glPopMatrix();
354  }
355 
356  if (cutawayUnion) glDisable (GL_CLIP_PLANE2);
357  } // iCutaway
358 
359  if (iPass == 2) secondPassForTransparencyRequested = false; // Done.
360  if (iPass == 3) thirdPassForNonHiddenMarkersRequested = false; // Done.
361 
362  if (secondPassForTransparencyRequested) iPass = 2;
363  else if (thirdPassForNonHiddenMarkersRequested) iPass = 3;
364  else break;
365 
366  } while (true);
367 
368  // Display time at "head" of time range, which is fEndTime...
369  if (fDisplayHeadTime && fEndTime < DBL_MAX) {
370  glMatrixMode (GL_PROJECTION);
371  glPushMatrix();
372  glLoadIdentity();
373  g4GlOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
374  glMatrixMode (GL_MODELVIEW);
375  glPushMatrix();
376  glLoadIdentity();
377  G4Text headTimeText(G4BestUnit(fEndTime,"Time"),
378  G4Point3D(fDisplayHeadTimeX, fDisplayHeadTimeY, 0.));
379  headTimeText.SetScreenSize(fDisplayHeadTimeSize);
380  G4VisAttributes visAtts (G4Colour
381  (fDisplayHeadTimeRed,
382  fDisplayHeadTimeGreen,
383  fDisplayHeadTimeBlue));
384  headTimeText.SetVisAttributes(&visAtts);
385  fOpenGLSceneHandler.G4OpenGLSceneHandler::AddPrimitive(headTimeText);
386  glMatrixMode (GL_PROJECTION);
387  glPopMatrix();
388  glMatrixMode (GL_MODELVIEW);
389  glPopMatrix();
390  }
391 
392  // Display light front...
393  if (fDisplayLightFront && fEndTime < DBL_MAX) {
394  G4double lightFrontRadius = (fEndTime - fDisplayLightFrontT) * c_light;
395  if (lightFrontRadius > 0.) {
396  G4Point3D lightFrontCentre(fDisplayLightFrontX, fDisplayLightFrontY, fDisplayLightFrontZ);
397  G4Point3D circleCentre = lightFrontCentre;
398  G4double circleRadius = lightFrontRadius;
399  if (fVP.GetFieldHalfAngle() > 0.) {
400  // Perspective view. Find horizon centre and radius...
401  G4Point3D targetPoint = fSceneHandler.GetScene()->GetStandardTargetPoint() +
402  fVP.GetCurrentTargetPoint();
403  G4double sceneRadius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
404  if(sceneRadius <= 0.) sceneRadius = 1.;
405  G4double cameraDistance = fVP.GetCameraDistance(sceneRadius);
406  G4Point3D cameraPosition = targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
407  G4Vector3D lightFrontToCameraDirection = cameraPosition - lightFrontCentre;
408  G4double lightFrontCentreDistance = lightFrontToCameraDirection.mag();
409  /*
410  G4cout << "cameraPosition: " << cameraPosition
411  << ", lightFrontCentre: " << lightFrontCentre
412  << ", lightFrontRadius: " << lightFrontRadius
413  << ", lightFrontCentreDistance: " << lightFrontCentreDistance
414  << ", dot: " << lightFrontToCameraDirection * fVP.GetViewpointDirection()
415  << G4endl;
416  */
417  if (lightFrontToCameraDirection * fVP.GetViewpointDirection() > 0. && lightFrontRadius < lightFrontCentreDistance) {
418  // Light front in front of camera...
419  G4double sineHorizonAngle = lightFrontRadius / lightFrontCentreDistance;
420  circleCentre = lightFrontCentre + (lightFrontRadius * sineHorizonAngle) * lightFrontToCameraDirection.unit();
421  circleRadius = lightFrontRadius * std::sqrt(1. - std::pow(sineHorizonAngle, 2));
422  /*
423  G4cout << "sineHorizonAngle: " << sineHorizonAngle
424  << ", circleCentre: " << circleCentre
425  << ", circleRadius: " << circleRadius
426  << G4endl;
427  */
428  } else {
429  circleRadius = -1.;
430  }
431  }
432  if (circleRadius > 0.) {
433  G4Circle lightFront(circleCentre);
434  lightFront.SetWorldRadius(circleRadius);
435  glColor3d(fDisplayLightFrontRed,
436  fDisplayLightFrontGreen,
437  fDisplayLightFrontBlue);
438  fOpenGLSceneHandler.G4OpenGLSceneHandler::AddPrimitive(lightFront);
439  }
440  }
441  }
442 }
443 
444 #endif
Definition: G4Text.hh:73
const G4Colour & GetBackgroundColour() const
G4double GetAlpha() const
Definition: G4Colour.hh:142
G4double GetVisibleDensity() const
G4bool IsCullingInvisible() const
G4double GetExplodeFactor() const
static G4bool GetColour(const G4String &key, G4Colour &result)
Definition: G4Colour.cc:126
const G4Colour & GetColour() const
G4bool IsDensityCulling() const
HepGeom::Point3D< G4double > G4Point3D
Definition: G4Point3D.hh:35
HepGeom::Vector3D< G4double > G4Vector3D
Definition: G4Vector3D.hh:35
G4double a
Definition: TRTMaterials.hh:39
G4double GetBlue() const
Definition: G4Colour.hh:141
#define G4BestUnit(a, b)
#define G4_USE_G4BESTUNIT_FOR_VERBOSE 1
int G4int
Definition: G4Types.hh:78
const std::vector< G4ModelingParameters::VisAttributesModifier > & GetVisAttributesModifiers() const
G4bool IsAuxEdgeVisible() const
G4double GetRed() const
Definition: G4Colour.hh:139
bool G4bool
Definition: G4Types.hh:79
G4double GetGreen() const
Definition: G4Colour.hh:140
std::vector< G4Plane3D > G4Planes
HepGeom::Transform3D G4Transform3D
G4bool IsCullingCovered() const
const G4VisAttributes * GetDefaultTextVisAttributes() const
G4bool IsExplode() const
G4bool IsSection() const
G4bool IsCutaway() const
G4int GetNoOfSides() const
DrawingStyle GetDrawingStyle() const
G4bool IsPicking() const
const G4VisAttributes * GetDefaultVisAttributes() const
double G4double
Definition: G4Types.hh:76
#define DBL_MAX
Definition: templates.hh:83
G4bool IsCulling() const