ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4OpenGLStoredViewer.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4OpenGLStoredViewer.cc
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 //
28 //
29 // Andrew Walkden 7th February 1997
30 // Class G4OpenGLStoredViewer : Encapsulates the `storedness' of
31 // an OpenGL view, for inheritance by
32 // derived (X, Xm...) classes.
33 
34 #ifdef G4VIS_BUILD_OPENGL_DRIVER
35 
36 #include "G4OpenGLStoredViewer.hh"
37 
38 #include "G4PhysicalConstants.hh"
40 #include "G4Text.hh"
41 #include "G4Circle.hh"
42 #include "G4UnitsTable.hh"
43 #include "G4Scene.hh"
44 #include "G4OpenGLTransform3D.hh"
45 
46 G4OpenGLStoredViewer::G4OpenGLStoredViewer
47 (G4OpenGLStoredSceneHandler& sceneHandler):
48 G4VViewer (sceneHandler, -1),
49 G4OpenGLViewer (sceneHandler),
50 fG4OpenGLStoredSceneHandler (sceneHandler),
51 fDepthTestEnable(true)
52 {
53  fLastVP = fDefaultVP; // Not sure if this gets executed before or
54  // after G4VViewer::G4VViewer!! Doesn't matter much.
55 }
56 
57 G4OpenGLStoredViewer::~G4OpenGLStoredViewer () {}
58 
59 void G4OpenGLStoredViewer::KernelVisitDecision () {
60 
61  // If there's a significant difference with the last view parameters
62  // of either the scene handler or this viewer, trigger a rebuild.
63 
64  if (!fG4OpenGLStoredSceneHandler.fTopPODL ||
65  CompareForKernelVisit(fLastVP)) {
66  NeedKernelVisit ();
67  }
68  fLastVP = fVP;
69 }
70 
71 G4bool G4OpenGLStoredViewer::CompareForKernelVisit(G4ViewParameters& lastVP) {
72 
73  if (
74  (lastVP.GetDrawingStyle () != fVP.GetDrawingStyle ()) ||
75  (lastVP.GetNumberOfCloudPoints() != fVP.GetNumberOfCloudPoints()) ||
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.GetCBDAlgorithmNumber() !=
82  fVP.GetCBDAlgorithmNumber()) ||
83  (lastVP.IsSection () != fVP.IsSection ()) ||
84  // Section (DCUT) implemented locally. But still need to visit
85  // kernel if status changes so that back plane culling can be
86  // switched.
87  (lastVP.IsCutaway () != fVP.IsCutaway ()) ||
88  // Cutaways implemented locally. But still need to visit kernel
89  // if status changes so that back plane culling can be switched.
90  (lastVP.IsExplode () != fVP.IsExplode ()) ||
91  (lastVP.GetNoOfSides () != fVP.GetNoOfSides ()) ||
92  (lastVP.GetDefaultVisAttributes()->GetColour() !=
93  fVP.GetDefaultVisAttributes()->GetColour()) ||
95  fVP.GetDefaultTextVisAttributes()->GetColour()) ||
96  (lastVP.GetBackgroundColour ()!= fVP.GetBackgroundColour ())||
97  (lastVP.IsPicking () != fVP.IsPicking ()) ||
98  (lastVP.GetVisAttributesModifiers() !=
99  fVP.GetVisAttributesModifiers())
100  )
101  return true;
102 
103  if (lastVP.IsDensityCulling () &&
104  (lastVP.GetVisibleDensity () != fVP.GetVisibleDensity ()))
105  return true;
106 
107 // /**************************************************************
108 // If section (DCUT) is implemented locally, comment this out.
109  if (lastVP.IsSection () &&
110  (lastVP.GetSectionPlane () != fVP.GetSectionPlane ()))
111  return true;
112 // ***************************************************************/
113 
114  /**************************************************************
115  If cutaways are implemented locally, comment this out.
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.GetCBDAlgorithmNumber() > 0) {
126  if (lastVP.GetCBDParameters().size() != fVP.GetCBDParameters().size()) return true;
127  else if (lastVP.GetCBDParameters() != fVP.GetCBDParameters()) return true;
128  }
129 
130  if (lastVP.IsExplode () &&
131  (lastVP.GetExplodeFactor () != fVP.GetExplodeFactor ()))
132  return true;
133 
134  // Time window parameters operate on the existing database so no need
135  // to rebuild even if they change.
136 
137  return false;
138 }
139 
140 void G4OpenGLStoredViewer::DrawDisplayLists () {
141 
142  // We moved these from G4OpenGLViewer to G4ViewParamaters. To avoid
143  // editing many lines below we introduce these convenient aliases.
144 #define CONVENIENT_DOUBLE_ALIAS(q) const G4double& f##q = fVP.Get##q();
145 #define CONVENIENT_BOOL_ALIAS(q) const G4bool& f##q = fVP.Is##q();
146  CONVENIENT_DOUBLE_ALIAS(StartTime)
147  CONVENIENT_DOUBLE_ALIAS(EndTime)
148  CONVENIENT_DOUBLE_ALIAS(FadeFactor)
149  CONVENIENT_BOOL_ALIAS(DisplayHeadTime)
150  CONVENIENT_DOUBLE_ALIAS(DisplayHeadTimeX)
151  CONVENIENT_DOUBLE_ALIAS(DisplayHeadTimeY)
152  CONVENIENT_DOUBLE_ALIAS(DisplayHeadTimeSize)
153  CONVENIENT_DOUBLE_ALIAS(DisplayHeadTimeRed)
154  CONVENIENT_DOUBLE_ALIAS(DisplayHeadTimeGreen)
155  CONVENIENT_DOUBLE_ALIAS(DisplayHeadTimeBlue)
156  CONVENIENT_BOOL_ALIAS(DisplayLightFront)
157  CONVENIENT_DOUBLE_ALIAS(DisplayLightFrontX)
158  CONVENIENT_DOUBLE_ALIAS(DisplayLightFrontY)
159  CONVENIENT_DOUBLE_ALIAS(DisplayLightFrontZ)
160  CONVENIENT_DOUBLE_ALIAS(DisplayLightFrontT)
161  CONVENIENT_DOUBLE_ALIAS(DisplayLightFrontRed)
162  CONVENIENT_DOUBLE_ALIAS(DisplayLightFrontGreen)
163  CONVENIENT_DOUBLE_ALIAS(DisplayLightFrontBlue)
164 
165  const G4Planes& cutaways = fVP.GetCutawayPlanes();
166  G4bool cutawayUnion = fVP.IsCutaway() &&
167  fVP.GetCutawayMode() == G4ViewParameters::cutawayUnion;
168  const size_t nCutaways = cutawayUnion? cutaways.size(): 1;
169  G4int iPass = 1;
170  G4bool secondPassForTransparencyRequested = false;
171  G4bool thirdPassForNonHiddenMarkersRequested = false;
172  fDepthTestEnable = true;
173  glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);
174  do {
175  for (size_t iCutaway = 0; iCutaway < nCutaways; ++iCutaway) {
176 
177  if (cutawayUnion) {
178  double a[4];
179  a[0] = cutaways[iCutaway].a();
180  a[1] = cutaways[iCutaway].b();
181  a[2] = cutaways[iCutaway].c();
182  a[3] = cutaways[iCutaway].d();
183  glClipPlane (GL_CLIP_PLANE2, a);
184  glEnable (GL_CLIP_PLANE2);
185  }
186 
187  G4bool isPicking = fVP.IsPicking();
188 
189  for (size_t iPO = 0;
190  iPO < fG4OpenGLStoredSceneHandler.fPOList.size(); ++iPO) {
191  if (POSelected(iPO)) {
192  G4OpenGLStoredSceneHandler::PO& po =
193  fG4OpenGLStoredSceneHandler.fPOList[iPO];
194  G4Colour c = po.fColour;
195  DisplayTimePOColourModification(c,iPO);
196  const G4bool isTransparent = c.GetAlpha() < 1.;
197  if ( iPass == 1) {
198  if (isTransparent && transparency_enabled) {
199  secondPassForTransparencyRequested = true;
200  continue;
201  }
202  if (po.fMarkerOrPolyline && fVP.IsMarkerNotHidden()) {
203  thirdPassForNonHiddenMarkersRequested = true;
204  continue;
205  }
206  } else if (iPass == 2) { // Second pass for transparency.
207  if (!isTransparent) {
208  continue;
209  }
210  } else { // Third pass for non-hidden markers
211  if (!po.fMarkerOrPolyline) {
212  continue;
213  }
214  }
215  if (isPicking) glLoadName(po.fPickName);
216  if (transparency_enabled) {
217  glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
218  } else {
219  glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
220  }
221  if (po.fMarkerOrPolyline && fVP.IsMarkerNotHidden()) {
222  if (fDepthTestEnable !=false) {
223  glDisable (GL_DEPTH_TEST);
224  fDepthTestEnable = false;
225  }
226  } else {
227  if (fDepthTestEnable !=true) {
228  glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);
229  fDepthTestEnable = true;
230  }
231  }
232  if (po.fpG4TextPlus) {
233  if (po.fpG4TextPlus->fProcessing2D) {
234  glMatrixMode (GL_PROJECTION);
235  glPushMatrix();
236  glLoadIdentity();
237  g4GlOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
238  glMatrixMode (GL_MODELVIEW);
239  glPushMatrix();
240  glLoadIdentity();
241  G4OpenGLTransform3D oglt (po.fTransform);
242  glMultMatrixd (oglt.GetGLMatrix ());
243  // This text is from a PODL. We don't want to create a new PODL.
244  AddPrimitiveForASingleFrame(po.fpG4TextPlus->fG4Text);
245  } else {
246  glPushMatrix();
247  G4OpenGLTransform3D oglt (po.fTransform);
248  glMultMatrixd (oglt.GetGLMatrix ());
249  // This text is from a PODL. We don't want to create a new PODL.
250  AddPrimitiveForASingleFrame(po.fpG4TextPlus->fG4Text);
251  glPopMatrix();
252  }
253 
254  if (po.fpG4TextPlus->fProcessing2D) {
255  glMatrixMode (GL_PROJECTION);
256  glPopMatrix();
257  glMatrixMode (GL_MODELVIEW);
258  glPopMatrix();
259  }
260  } else {
261  glPushMatrix();
262  G4OpenGLTransform3D oglt (po.fTransform);
263  glMultMatrixd (oglt.GetGLMatrix ());
264  glCallList (po.fDisplayListId);
265  glPopMatrix();
266  }
267  }
268  }
269 
270  G4Transform3D lastMatrixTransform;
271  G4bool first = true;
272 
273  for (size_t iTO = 0;
274  iTO < fG4OpenGLStoredSceneHandler.fTOList.size(); ++iTO) {
275  if (TOSelected(iTO)) {
276  G4OpenGLStoredSceneHandler::TO& to =
277  fG4OpenGLStoredSceneHandler.fTOList[iTO];
278  const G4Colour& c = to.fColour;
279  const G4bool isTransparent = c.GetAlpha() < 1.;
280  if ( iPass == 1) {
281  if (isTransparent && transparency_enabled) {
282  secondPassForTransparencyRequested = true;
283  continue;
284  }
285  if (to.fMarkerOrPolyline && fVP.IsMarkerNotHidden()) {
286  thirdPassForNonHiddenMarkersRequested = true;
287  continue;
288  }
289  } else if (iPass == 2) { // Second pass for transparency.
290  if (!isTransparent) {
291  continue;
292  }
293  } else { // Third pass for non-hidden markers
294  if (!to.fMarkerOrPolyline) {
295  continue;
296  }
297  }
298  if (to.fMarkerOrPolyline && fVP.IsMarkerNotHidden()) {
299  if (fDepthTestEnable !=false) {
300  glDisable (GL_DEPTH_TEST);
301  fDepthTestEnable = false;
302  }
303  } else {
304  if (fDepthTestEnable !=true) {
305  glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);
306  fDepthTestEnable = true;
307  }
308  }
309  if (to.fEndTime >= fStartTime && to.fStartTime <= fEndTime) {
310  if (fVP.IsPicking()) glLoadName(to.fPickName);
311  if (to.fpG4TextPlus) {
312  if (to.fpG4TextPlus->fProcessing2D) {
313  glMatrixMode (GL_PROJECTION);
314  glPushMatrix();
315  glLoadIdentity();
316  g4GlOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
317  glMatrixMode (GL_MODELVIEW);
318  glPushMatrix();
319  glLoadIdentity();
320  }
321  G4OpenGLTransform3D oglt (to.fTransform);
322  glMultMatrixd (oglt.GetGLMatrix ());
323  // This text is from a TODL. We don't want to create a new TODL.
324  AddPrimitiveForASingleFrame(to.fpG4TextPlus->fG4Text);
325  if (to.fpG4TextPlus->fProcessing2D) {
326  glMatrixMode (GL_PROJECTION);
327  glPopMatrix();
328  glMatrixMode (GL_MODELVIEW);
329  glPopMatrix();
330  }
331  } else {
332  if (to.fTransform != lastMatrixTransform) {
333  if (! first) {
334  glPopMatrix();
335  }
336  first = false;
337  glPushMatrix();
338  G4OpenGLTransform3D oglt (to.fTransform);
339  glMultMatrixd (oglt.GetGLMatrix ());
340  }
341  const G4Colour& cc = to.fColour;
342  if (fFadeFactor > 0. && to.fEndTime < fEndTime) {
343  // Brightness scaling factor
344  G4double bsf = 1. - fFadeFactor *
345  ((fEndTime - to.fEndTime) / (fEndTime - fStartTime));
346  const G4Colour& bg = fVP.GetBackgroundColour();
347  if (transparency_enabled) {
348  glColor4d
349  (bsf * cc.GetRed() + (1. - bsf) * bg.GetRed(),
350  bsf * cc.GetGreen() + (1. - bsf) * bg.GetGreen(),
351  bsf * cc.GetBlue() + (1. - bsf) * bg.GetBlue(),
352  bsf * cc.GetAlpha() + (1. - bsf) * bg.GetAlpha());
353  } else {
354  glColor3d
355  (bsf * cc.GetRed() + (1. - bsf) * bg.GetRed(),
356  bsf * cc.GetGreen() + (1. - bsf) * bg.GetGreen(),
357  bsf * cc.GetBlue() + (1. - bsf) * bg.GetBlue());
358  }
359  } else {
360  if (transparency_enabled) {
361  glColor4d(cc.GetRed(),cc.GetGreen(),cc.GetBlue(),cc.GetAlpha());
362  } else {
363  glColor3d(cc.GetRed(),cc.GetGreen(),cc.GetBlue());
364  }
365  }
366  glCallList (to.fDisplayListId);
367  }
368  if (to.fTransform != lastMatrixTransform) {
369  lastMatrixTransform = to.fTransform;
370  }
371  }
372  }
373  }
374  if (! first) {
375  glPopMatrix();
376  }
377 
378  if (cutawayUnion) glDisable (GL_CLIP_PLANE2);
379  } // iCutaway
380 
381  if (iPass == 2) secondPassForTransparencyRequested = false; // Done.
382  if (iPass == 3) thirdPassForNonHiddenMarkersRequested = false; // Done.
383 
384  if (secondPassForTransparencyRequested) iPass = 2;
385  else if (thirdPassForNonHiddenMarkersRequested) iPass = 3;
386  else break;
387 
388  } while (true);
389 
390  // Display time at "head" of time range, which is fEndTime...
391  if (fDisplayHeadTime && fEndTime < G4VisAttributes::fVeryLongTime) {
392  glMatrixMode (GL_PROJECTION);
393  glPushMatrix();
394  glLoadIdentity();
395  g4GlOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
396  glMatrixMode (GL_MODELVIEW);
397  glPushMatrix();
398  glLoadIdentity();
399  G4Text headTimeText(G4BestUnit(fEndTime,"Time"),
400  G4Point3D(fDisplayHeadTimeX, fDisplayHeadTimeY, 0.));
401  headTimeText.SetScreenSize(fDisplayHeadTimeSize);
402  G4VisAttributes visAtts (G4Colour
403  (fDisplayHeadTimeRed,
404  fDisplayHeadTimeGreen,
405  fDisplayHeadTimeBlue));
406  headTimeText.SetVisAttributes(&visAtts);
407  AddPrimitiveForASingleFrame(headTimeText);
408  glMatrixMode (GL_PROJECTION);
409  glPopMatrix();
410  glMatrixMode (GL_MODELVIEW);
411  glPopMatrix();
412  }
413 
414  // Display light front...
415  if (fDisplayLightFront && fEndTime < G4VisAttributes::fVeryLongTime) {
416  G4double lightFrontRadius = (fEndTime - fDisplayLightFrontT) * c_light;
417  if (lightFrontRadius > 0.) {
418  G4Point3D lightFrontCentre(fDisplayLightFrontX, fDisplayLightFrontY, fDisplayLightFrontZ);
419  G4Point3D circleCentre = lightFrontCentre;
420  G4double circleRadius = lightFrontRadius;
421  if (fVP.GetFieldHalfAngle() > 0.) {
422  // Perspective view. Find horizon centre and radius...
423  G4Point3D targetPoint = fSceneHandler.GetScene()->GetStandardTargetPoint() +
424  fVP.GetCurrentTargetPoint();
425  G4double sceneRadius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
426  if(sceneRadius <= 0.) sceneRadius = 1.;
427  G4double cameraDistance = fVP.GetCameraDistance(sceneRadius);
428  G4Point3D cameraPosition = targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
429  G4Vector3D lightFrontToCameraDirection = cameraPosition - lightFrontCentre;
430  G4double lightFrontCentreDistance = lightFrontToCameraDirection.mag();
431  /*
432  G4cout << "cameraPosition: " << cameraPosition
433  << ", lightFrontCentre: " << lightFrontCentre
434  << ", lightFrontRadius: " << lightFrontRadius
435  << ", lightFrontCentreDistance: " << lightFrontCentreDistance
436  << ", dot: " << lightFrontToCameraDirection * fVP.GetViewpointDirection()
437  << G4endl;
438  */
439  if (lightFrontToCameraDirection * fVP.GetViewpointDirection() > 0. && lightFrontRadius < lightFrontCentreDistance) {
440  // Light front in front of camera...
441  G4double sineHorizonAngle = lightFrontRadius / lightFrontCentreDistance;
442  circleCentre = lightFrontCentre + (lightFrontRadius * sineHorizonAngle) * lightFrontToCameraDirection.unit();
443  circleRadius = lightFrontRadius * std::sqrt(1. - std::pow(sineHorizonAngle, 2));
444  /*
445  G4cout << "sineHorizonAngle: " << sineHorizonAngle
446  << ", circleCentre: " << circleCentre
447  << ", circleRadius: " << circleRadius
448  << G4endl;
449  */
450  } else {
451  circleRadius = -1.;
452  }
453  }
454  if (circleRadius > 0.) {
455  G4Circle lightFront(circleCentre);
456  lightFront.SetWorldRadius(circleRadius);
457  G4VisAttributes visAtts(G4Colour
458  (fDisplayLightFrontRed,
459  fDisplayLightFrontGreen,
460  fDisplayLightFrontBlue));
461  lightFront.SetVisAttributes(visAtts);
462  AddPrimitiveForASingleFrame(lightFront);
463  }
464  }
465  }
466 }
467 
468 void G4OpenGLStoredViewer::AddPrimitiveForASingleFrame(const G4Text& text)
469 {
470  // We don't want this to get into a display list or a TODL or a PODL so
471  // use the fMemoryForDisplayLists flag.
472  G4bool memoryForDisplayListsKeep = fG4OpenGLStoredSceneHandler.fMemoryForDisplayLists;
473  fG4OpenGLStoredSceneHandler.fMemoryForDisplayLists = false;
474  fG4OpenGLStoredSceneHandler.G4OpenGLStoredSceneHandler::AddPrimitive(text);
475  fG4OpenGLStoredSceneHandler.fMemoryForDisplayLists = memoryForDisplayListsKeep;
476 }
477 
478 void G4OpenGLStoredViewer::AddPrimitiveForASingleFrame(const G4Circle& circle)
479 {
480  // We don't want this to get into a display list or a TODL or a PODL so
481  // use the fMemoryForDisplayLists flag.
482  G4bool memoryForDisplayListsKeep = fG4OpenGLStoredSceneHandler.fMemoryForDisplayLists;
483  fG4OpenGLStoredSceneHandler.fMemoryForDisplayLists = false;
484  fG4OpenGLStoredSceneHandler.G4OpenGLStoredSceneHandler::AddPrimitive(circle);
485  fG4OpenGLStoredSceneHandler.fMemoryForDisplayLists = memoryForDisplayListsKeep;
486 }
487 
488 #endif