Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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$
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 {
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.IsAuxEdgeVisible () != fVP.IsAuxEdgeVisible ()) ||
76  (lastVP.GetRepStyle () != fVP.GetRepStyle ()) ||
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 #ifdef G4DEBUG_VIS_OGL
134  printf("G4OpenGLStoredViewer::DrawDisplayLists \n");
135 #endif
136 
137  const G4Planes& cutaways = fVP.GetCutawayPlanes();
138  G4bool cutawayUnion = fVP.IsCutaway() &&
139  fVP.GetCutawayMode() == G4ViewParameters::cutawayUnion;
140  const size_t nCutaways = cutawayUnion? cutaways.size(): 1;
141 #ifdef G4DEBUG_VIS_OGL
142  printf("G4OpenGLStoredViewer::DrawDisplayLists");
143 #endif
144  G4int iPass = 1;
145  G4bool secondPassForTransparencyRequested = false;
146  G4bool thirdPassForNonHiddenMarkersRequested = false;
147  do {
148  for (size_t iCutaway = 0; iCutaway < nCutaways; ++iCutaway) {
149 
150  if (cutawayUnion) {
151  double a[4];
152  a[0] = cutaways[iCutaway].a();
153  a[1] = cutaways[iCutaway].b();
154  a[2] = cutaways[iCutaway].c();
155  a[3] = cutaways[iCutaway].d();
156  glClipPlane (GL_CLIP_PLANE2, a);
157  glEnable (GL_CLIP_PLANE2);
158  }
159 
160  G4bool isPicking = fVP.IsPicking();
161 
162  for (size_t iPO = 0;
163  iPO < fG4OpenGLStoredSceneHandler.fPOList.size(); ++iPO) {
164  if (POSelected(iPO)) {
165  G4OpenGLStoredSceneHandler::PO& po =
166  fG4OpenGLStoredSceneHandler.fPOList[iPO];
167  G4Colour c = po.fColour;
168  DisplayTimePOColourModification(c,iPO);
169  const G4bool isTransparent = c.GetAlpha() < 1.;
170  if ( iPass == 1) {
171  if (isTransparent && transparency_enabled) {
172  secondPassForTransparencyRequested = true;
173  continue;
174  }
175  if (po.fMarkerOrPolyline && fVP.IsMarkerNotHidden()) {
176  thirdPassForNonHiddenMarkersRequested = true;
177  continue;
178  }
179  } else if (iPass == 2) { // Second pass for transparency.
180  if (!isTransparent) {
181  continue;
182  }
183  } else { // Third pass for non-hidden markers
184  if (!po.fMarkerOrPolyline) {
185  continue;
186  }
187  }
188  if (isPicking) glLoadName(po.fPickName);
189  if (transparency_enabled) {
190  glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
191  } else {
192  glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
193  }
194  if (po.fMarkerOrPolyline && fVP.IsMarkerNotHidden())
195  glDisable (GL_DEPTH_TEST);
196  else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);}
197  if (po.fpG4TextPlus) {
198  if (po.fpG4TextPlus->fProcessing2D) {
199  glMatrixMode (GL_PROJECTION);
200  glPushMatrix();
201  glLoadIdentity();
202  glOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
203  glMatrixMode (GL_MODELVIEW);
204  glPushMatrix();
205  glLoadIdentity();
206  }
207  G4OpenGLTransform3D oglt (po.fTransform);
208  glMultMatrixd (oglt.GetGLMatrix ());
209  fOpenGLSceneHandler.G4OpenGLSceneHandler::AddPrimitive
210  (po.fpG4TextPlus->fG4Text);
211  if (po.fpG4TextPlus->fProcessing2D) {
212  glMatrixMode (GL_PROJECTION);
213  glPopMatrix();
214  glMatrixMode (GL_MODELVIEW);
215  glPopMatrix();
216  }
217  } else {
218  glPushMatrix();
219  G4OpenGLTransform3D oglt (po.fTransform);
220  glMultMatrixd (oglt.GetGLMatrix ());
221  glCallList (po.fDisplayListId);
222  glPopMatrix();
223  }
224  }
225  }
226 
227  G4Transform3D lastMatrixTransform;
228  G4bool first = true;
229 
230  for (size_t iTO = 0;
231  iTO < fG4OpenGLStoredSceneHandler.fTOList.size(); ++iTO) {
232  if (TOSelected(iTO)) {
233  G4OpenGLStoredSceneHandler::TO& to =
234  fG4OpenGLStoredSceneHandler.fTOList[iTO];
235  const G4Colour& c = to.fColour;
236  const G4bool isTransparent = c.GetAlpha() < 1.;
237  if ( iPass == 1) {
238  if (isTransparent && transparency_enabled) {
239  secondPassForTransparencyRequested = true;
240  continue;
241  }
242  if (to.fMarkerOrPolyline && fVP.IsMarkerNotHidden()) {
243  thirdPassForNonHiddenMarkersRequested = true;
244  continue;
245  }
246  } else if (iPass == 2) { // Second pass for transparency.
247  if (!isTransparent) {
248  continue;
249  }
250  } else { // Third pass for non-hidden markers
251  if (!to.fMarkerOrPolyline) {
252  continue;
253  }
254  }
255  if (to.fMarkerOrPolyline && fVP.IsMarkerNotHidden())
256  glDisable (GL_DEPTH_TEST);
257  else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);}
258  if (to.fEndTime >= fStartTime && to.fStartTime <= fEndTime) {
259  if (fVP.IsPicking()) glLoadName(to.fPickName);
260  if (to.fpG4TextPlus) {
261  if (to.fpG4TextPlus->fProcessing2D) {
262  glMatrixMode (GL_PROJECTION);
263  glPushMatrix();
264  glLoadIdentity();
265  glOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
266  glMatrixMode (GL_MODELVIEW);
267  glPushMatrix();
268  glLoadIdentity();
269  }
270  G4OpenGLTransform3D oglt (to.fTransform);
271  glMultMatrixd (oglt.GetGLMatrix ());
272  if (transparency_enabled) {
273  glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
274  } else {
275  glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
276  }
277  fOpenGLSceneHandler.G4OpenGLSceneHandler::AddPrimitive
278  (to.fpG4TextPlus->fG4Text);
279  if (to.fpG4TextPlus->fProcessing2D) {
280  glMatrixMode (GL_PROJECTION);
281  glPopMatrix();
282  glMatrixMode (GL_MODELVIEW);
283  glPopMatrix();
284  }
285  } else {
286  if (to.fTransform != lastMatrixTransform) {
287  if (! first) {
288  glPopMatrix();
289  }
290  first = false;
291  glPushMatrix();
292  G4OpenGLTransform3D oglt (to.fTransform);
293  glMultMatrixd (oglt.GetGLMatrix ());
294  }
295  const G4Colour& cc = to.fColour;
296  if (fFadeFactor > 0. && to.fEndTime < fEndTime) {
297  // Brightness scaling factor
298  G4double bsf = 1. - fFadeFactor *
299  ((fEndTime - to.fEndTime) / (fEndTime - fStartTime));
300  const G4Colour& bg = fVP.GetBackgroundColour();
301  if (transparency_enabled) {
302  glColor4d
303  (bsf * cc.GetRed() + (1. - bsf) * bg.GetRed(),
304  bsf * cc.GetGreen() + (1. - bsf) * bg.GetGreen(),
305  bsf * cc.GetBlue() + (1. - bsf) * bg.GetBlue(),
306  bsf * cc.GetAlpha() + (1. - bsf) * bg.GetAlpha());
307  } else {
308  glColor3d
309  (bsf * cc.GetRed() + (1. - bsf) * bg.GetRed(),
310  bsf * cc.GetGreen() + (1. - bsf) * bg.GetGreen(),
311  bsf * cc.GetBlue() + (1. - bsf) * bg.GetBlue());
312  }
313  } else {
314  if (transparency_enabled) {
315  glColor4d(cc.GetRed(),cc.GetGreen(),cc.GetBlue(),cc.GetAlpha());
316  } else {
317  glColor3d(cc.GetRed(),cc.GetGreen(),cc.GetBlue());
318  }
319  }
320  glCallList (to.fDisplayListId);
321  }
322  if (to.fTransform != lastMatrixTransform) {
323  lastMatrixTransform = to.fTransform;
324  }
325  }
326  }
327  }
328  if (! first) {
329  glPopMatrix();
330  }
331 
332  if (cutawayUnion) glDisable (GL_CLIP_PLANE2);
333  } // iCutaway
334 
335  if (iPass == 2) secondPassForTransparencyRequested = false; // Done.
336  if (iPass == 3) thirdPassForNonHiddenMarkersRequested = false; // Done.
337 
338  if (secondPassForTransparencyRequested) iPass = 2;
339  else if (thirdPassForNonHiddenMarkersRequested) iPass = 3;
340  else break;
341 
342  } while (true);
343 
344  // Display time at "head" of time range, which is fEndTime...
345  if (fDisplayHeadTime && fEndTime < DBL_MAX) {
346  glMatrixMode (GL_PROJECTION);
347  glPushMatrix();
348  glLoadIdentity();
349  glOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
350  glMatrixMode (GL_MODELVIEW);
351  glPushMatrix();
352  glLoadIdentity();
353  G4Text headTimeText(G4BestUnit(fEndTime,"Time"),
354  G4Point3D(fDisplayHeadTimeX, fDisplayHeadTimeY, 0.));
355  headTimeText.SetScreenSize(fDisplayHeadTimeSize);
356  G4VisAttributes visAtts (G4Colour
357  (fDisplayHeadTimeRed,
358  fDisplayHeadTimeGreen,
359  fDisplayHeadTimeBlue));
360  headTimeText.SetVisAttributes(&visAtts);
361  fOpenGLSceneHandler.G4OpenGLSceneHandler::AddPrimitive(headTimeText);
362  glMatrixMode (GL_PROJECTION);
363  glPopMatrix();
364  glMatrixMode (GL_MODELVIEW);
365  glPopMatrix();
366  }
367 
368  // Display light front...
369  if (fDisplayLightFront && fEndTime < DBL_MAX) {
370  G4double lightFrontRadius = (fEndTime - fDisplayLightFrontT) * c_light;
371  if (lightFrontRadius > 0.) {
372  G4Point3D lightFrontCentre(fDisplayLightFrontX, fDisplayLightFrontY, fDisplayLightFrontZ);
373  G4Point3D circleCentre = lightFrontCentre;
374  G4double circleRadius = lightFrontRadius;
375  if (fVP.GetFieldHalfAngle() > 0.) {
376  // Perspective view. Find horizon centre and radius...
377  G4Point3D targetPoint = fSceneHandler.GetScene()->GetStandardTargetPoint() +
378  fVP.GetCurrentTargetPoint();
379  G4double sceneRadius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
380  if(sceneRadius <= 0.) sceneRadius = 1.;
381  G4double cameraDistance = fVP.GetCameraDistance(sceneRadius);
382  G4Point3D cameraPosition = targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
383  G4Vector3D lightFrontToCameraDirection = cameraPosition - lightFrontCentre;
384  G4double lightFrontCentreDistance = lightFrontToCameraDirection.mag();
385  /*
386  G4cout << "cameraPosition: " << cameraPosition
387  << ", lightFrontCentre: " << lightFrontCentre
388  << ", lightFrontRadius: " << lightFrontRadius
389  << ", lightFrontCentreDistance: " << lightFrontCentreDistance
390  << ", dot: " << lightFrontToCameraDirection * fVP.GetViewpointDirection()
391  << G4endl;
392  */
393  if (lightFrontToCameraDirection * fVP.GetViewpointDirection() > 0. && lightFrontRadius < lightFrontCentreDistance) {
394  // Light front in front of camera...
395  G4double sineHorizonAngle = lightFrontRadius / lightFrontCentreDistance;
396  circleCentre = lightFrontCentre + (lightFrontRadius * sineHorizonAngle) * lightFrontToCameraDirection.unit();
397  circleRadius = lightFrontRadius * std::sqrt(1. - std::pow(sineHorizonAngle, 2));
398  /*
399  G4cout << "sineHorizonAngle: " << sineHorizonAngle
400  << ", circleCentre: " << circleCentre
401  << ", circleRadius: " << circleRadius
402  << G4endl;
403  */
404  } else {
405  circleRadius = -1.;
406  }
407  }
408  if (circleRadius > 0.) {
409  G4Circle lightFront(circleCentre);
410  lightFront.SetWorldRadius(circleRadius);
411  glColor3d(fDisplayLightFrontRed,
412  fDisplayLightFrontGreen,
413  fDisplayLightFrontBlue);
414  fOpenGLSceneHandler.G4OpenGLSceneHandler::AddPrimitive(lightFront);
415  }
416  }
417  }
418 }
419 
420 #endif