Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4OpenGLStoredSceneHandler.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 10th February 1997
31 // OpenGL stored scene - creates OpenGL display lists.
32 
33 #ifdef G4VIS_BUILD_OPENGL_DRIVER
34 
35 // Included here - problems with HP compiler if not before other includes?
36 #include "G4NURBS.hh"
37 
38 // Here follows a special for Mesa, the OpenGL emulator. Does not affect
39 // other OpenGL's, as far as I'm aware. John Allison 18/9/96.
40 #define CENTERLINE_CLPP /* CenterLine C++ workaround: */
41 // Also seems to be required for HP's CC and AIX xlC, at least.
42 
44 
45 #include "G4PhysicalVolumeModel.hh"
46 #include "G4LogicalVolumeModel.hh"
47 #include "G4VPhysicalVolume.hh"
48 #include "G4LogicalVolume.hh"
49 #include "G4Polyline.hh"
50 #include "G4Polymarker.hh"
51 #include "G4Text.hh"
52 #include "G4Circle.hh"
53 #include "G4Square.hh"
54 #include "G4Polyhedron.hh"
55 #include "G4AttHolder.hh"
56 #include "G4OpenGLTransform3D.hh"
57 #include "G4OpenGLViewer.hh"
58 #include "G4AttHolder.hh"
59 
60 #include <typeinfo>
61 
62 G4OpenGLStoredSceneHandler::PO::PO():
63  fDisplayListId(0),
64  fPickName(0),
65  fpG4TextPlus(0),
66  fMarkerOrPolyline(false)
67 {}
68 
69 G4OpenGLStoredSceneHandler::PO::PO(const G4OpenGLStoredSceneHandler::PO& po):
70  fDisplayListId(po.fDisplayListId),
71  fTransform(po.fTransform),
72  fPickName(po.fPickName),
73  fColour(po.fColour),
74  fpG4TextPlus(po.fpG4TextPlus? new G4TextPlus(*po.fpG4TextPlus): 0),
75  fMarkerOrPolyline(po.fMarkerOrPolyline)
76 {}
77 
78 G4OpenGLStoredSceneHandler::PO::PO(G4int id, const G4Transform3D& tr):
79  fDisplayListId(id),
80  fTransform(tr),
81  fPickName(0),
82  fpG4TextPlus(0),
83  fMarkerOrPolyline(false)
84 {}
85 
86 G4OpenGLStoredSceneHandler::PO::~PO()
87 {
88  delete fpG4TextPlus;
89 }
90 
91 G4OpenGLStoredSceneHandler::PO& G4OpenGLStoredSceneHandler::PO::operator=
92  (const G4OpenGLStoredSceneHandler::PO& rhs)
93 {
94  if (&rhs == this) return *this;
95  fDisplayListId = rhs.fDisplayListId;
96  fTransform = rhs.fTransform;
97  fPickName = rhs.fPickName;
98  fColour = rhs.fColour;
99  fpG4TextPlus = rhs.fpG4TextPlus? new G4TextPlus(*rhs.fpG4TextPlus): 0;
100  fMarkerOrPolyline = rhs.fMarkerOrPolyline;
101  return *this;
102 }
103 
104 G4OpenGLStoredSceneHandler::TO::TO():
105  fDisplayListId(0),
106  fPickName(0),
107  fStartTime(-DBL_MAX),
108  fEndTime(DBL_MAX),
109  fpG4TextPlus(0),
110  fMarkerOrPolyline(false)
111 {}
112 
113 G4OpenGLStoredSceneHandler::TO::TO(const G4OpenGLStoredSceneHandler::TO& to):
114  fDisplayListId(to.fDisplayListId),
115  fTransform(to.fTransform),
116  fPickName(to.fPickName),
117  fStartTime(to.fStartTime),
118  fEndTime(to.fEndTime),
119  fColour(to.fColour),
120  fpG4TextPlus(to.fpG4TextPlus? new G4TextPlus(*to.fpG4TextPlus): 0),
121  fMarkerOrPolyline(to.fMarkerOrPolyline)
122 {}
123 
124 G4OpenGLStoredSceneHandler::TO::TO(G4int id, const G4Transform3D& tr):
125  fDisplayListId(id),
126  fTransform(tr),
127  fPickName(0),
128  fStartTime(-DBL_MAX),
129  fEndTime(DBL_MAX),
130  fpG4TextPlus(0),
131  fMarkerOrPolyline(false)
132 {}
133 
134 G4OpenGLStoredSceneHandler::TO::~TO()
135 {
136  delete fpG4TextPlus;
137 }
138 
139 G4OpenGLStoredSceneHandler::TO& G4OpenGLStoredSceneHandler::TO::operator=
140  (const G4OpenGLStoredSceneHandler::TO& rhs)
141 {
142  if (&rhs == this) return *this;
143  fDisplayListId = rhs.fDisplayListId;
144  fTransform = rhs.fTransform;
145  fPickName = rhs.fPickName;
146  fStartTime = rhs.fStartTime;
147  fEndTime = rhs.fEndTime;
148  fColour = rhs.fColour;
149  fpG4TextPlus = rhs.fpG4TextPlus? new G4TextPlus(*rhs.fpG4TextPlus): 0;
150  fMarkerOrPolyline = rhs.fMarkerOrPolyline;
151  return *this;
152 }
153 
154 G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler
155 (G4VGraphicsSystem& system,
156  const G4String& name):
157 G4OpenGLSceneHandler (system, fSceneIdCount++, name),
158 fTopPODL (0)
159 {}
160 
161 G4OpenGLStoredSceneHandler::~G4OpenGLStoredSceneHandler ()
162 {}
163 
164 void G4OpenGLStoredSceneHandler::BeginPrimitives
165 (const G4Transform3D& objectTransformation)
166 {
167  G4OpenGLSceneHandler::BeginPrimitives (objectTransformation);
168  if (fReadyForTransients) glDrawBuffer (GL_FRONT);
169  // Display list setup moved to AddPrimitivePreamble. See notes there.
170 }
171 
172 void G4OpenGLStoredSceneHandler::EndPrimitives ()
173 {
174  // See all primitives immediately... At least soon...
175  ScaledFlush();
176  glDrawBuffer (GL_BACK);
177  G4OpenGLSceneHandler::EndPrimitives ();
178 }
179 
180 void G4OpenGLStoredSceneHandler::BeginPrimitives2D
181 (const G4Transform3D& objectTransformation)
182 {
183  G4OpenGLSceneHandler::BeginPrimitives2D(objectTransformation);
184  if (fReadyForTransients) glDrawBuffer (GL_FRONT);
185 }
186 
187 void G4OpenGLStoredSceneHandler::EndPrimitives2D ()
188 {
189  // See all primitives immediately... At least soon...
190  ScaledFlush();
191  glDrawBuffer (GL_BACK);
192  G4OpenGLSceneHandler::EndPrimitives2D ();
193 }
194 
195 G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Visible& visible)
196 {
197  const G4Colour& c = GetColour (visible);
198  G4double opacity = c.GetAlpha ();
199 
200  G4bool transparency_enabled = true;
201  G4bool isMarkerNotHidden = true;
202  G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
203  if (pViewer) {
204  transparency_enabled = pViewer->transparency_enabled;
205  isMarkerNotHidden = pViewer->fVP.IsMarkerNotHidden();
206  }
207 
208  G4bool isMarker = false;
209  try {
210  (void) dynamic_cast<const G4VMarker&>(visible);
211  isMarker = true;
212  }
213  catch (std::bad_cast) {}
214 
215  G4bool isPolyline = false;
216  try {
217  (void) dynamic_cast<const G4Polyline&>(visible);
218  isPolyline = true;
219  }
220  catch (std::bad_cast) {}
221 
222  G4bool isTransparent = opacity < 1.;
223  G4bool isMarkerOrPolyline = isMarker || isPolyline;
224  G4bool treatAsTransparent = transparency_enabled && isTransparent;
225  G4bool treatAsNotHidden = isMarkerNotHidden && isMarkerOrPolyline;
226 
227  if (fProcessing2D) glDisable (GL_DEPTH_TEST);
228  else {
229  if (isMarkerOrPolyline && isMarkerNotHidden)
230  glDisable (GL_DEPTH_TEST);
231  else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);}
232  }
233 
234  if (fThreePassCapable) {
235 
236  // Ensure transparent objects are drawn opaque ones and before
237  // non-hidden markers. The problem of blending/transparency/alpha
238  // is quite a tricky one - see History of opengl-V07-01-01/2/3.
239  if (!(fSecondPassForTransparency || fThirdPassForNonHiddenMarkers)) {
240  // First pass...
241  if (treatAsTransparent) { // Request pass for transparent objects...
242  fSecondPassForTransparencyRequested = true;
243  }
244  if (treatAsNotHidden) { // Request pass for non-hidden markers...
245  fThirdPassForNonHiddenMarkersRequested = true;
246  }
247  // On first pass, transparent objects and non-hidden markers are not drawn...
248  if (treatAsTransparent || treatAsNotHidden) {
249  return false; // No further processing.
250  }
251  }
252 
253  // On second pass, only transparent objects are drawn...
254  if (fSecondPassForTransparency) {
255  if (!treatAsTransparent) {
256  return false; // No further processing.
257  }
258  }
259 
260  // On third pass, only non-hidden markers are drawn...
261  if (fThirdPassForNonHiddenMarkers) {
262  if (!treatAsNotHidden) {
263  return false; // No further processing.
264 
265  }
266  }
267  } // fThreePassCapable
268 
269  // Loads G4Atts for picking...
270  G4bool isPicking = false;
271  if (fpViewer->GetViewParameters().IsPicking()) {
272  isPicking = true;
273  glLoadName(++fPickName);
274  G4AttHolder* holder = new G4AttHolder;
275  LoadAtts(visible, holder);
276  fPickMap[fPickName] = holder;
277  }
278 
279  // Can we re-use a display list?
280  const G4VSolid* pSolid = 0;
281  G4PhysicalVolumeModel* pPVModel =
282  dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
283  if (fpViewer->GetViewParameters().GetVisAttributesModifiers().size())
284  // Touchables have been modified - don't risk re-using display list.
285  goto end_of_display_list_reuse_test;
286  if (pPVModel) {
287  // Check that it isn't a G4LogicalVolumeModel (which is a sub-class of
288  // G4PhysicalVolumeModel).
289  G4LogicalVolumeModel* pLVModel =
290  dynamic_cast<G4LogicalVolumeModel*>(pPVModel);
291  if (pLVModel)
292  // Logical volume model - don't re-use.
293  goto end_of_display_list_reuse_test;
294  // If part of the geometry hierarchy, i.e., from a
295  // G4PhysicalVolumeModel, check if a display list already exists for
296  // this solid, re-use it if possible. We could be smarter, and
297  // recognise repeated branches of the geometry hierarchy, for
298  // example. But this algorithm should be secure, I think...
299  pSolid = pPVModel->GetCurrentPV()->GetLogicalVolume()->GetSolid();
300  EAxis axis = kRho;
301  G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
302  if (pCurrentPV -> IsReplicated ()) {
303  G4int nReplicas;
304  G4double width;
305  G4double offset;
306  G4bool consuming;
307  pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
308  }
309  // Provided it is not parametrised (because if so, the
310  // solid's parameters might have been changed)...
311  if (!(pCurrentPV -> IsParameterised ()) &&
312  // Provided it is not replicated radially (because if so, the
313  // solid's parameters will have been changed)...
314  !(pCurrentPV -> IsReplicated () && axis == kRho) &&
315  // ...and if the solid has already been rendered...
316  (fSolidMap.find (pSolid) != fSolidMap.end ())) {
317  fDisplayListId = fSolidMap [pSolid];
318  PO po(fDisplayListId,fObjectTransformation);
319  if (isPicking) po.fPickName = fPickName;
320  po.fColour = c;
321  po.fMarkerOrPolyline = isMarkerOrPolyline;
322  fPOList.push_back(po);
323  // No need to test if gl commands are used (result of
324  // ExtraPOProcessing) because we have already decided they will
325  // not, at least not here. Also, pass a dummy G4Visible since
326  // not relevant for G4PhysicalVolumeModel.
327  (void) ExtraPOProcessing(G4Visible(), fPOList.size() - 1);
328  return false; // No further processing.
329  }
330  }
331 end_of_display_list_reuse_test:
332 
333  // Because of our need to control colour of transients (display by
334  // time fading), display lists may only cover a single primitive.
335  // So display list setup is here.
336 
337  if (fMemoryForDisplayLists) {
338  fDisplayListId = glGenLists (1);
339  if (glGetError() == GL_OUT_OF_MEMORY ||
340  fDisplayListId > fDisplayListLimit) {
341  G4cout <<
342  "********************* WARNING! ********************"
343  "\n* Display list limit reached in OpenGL."
344  "\n* Continuing drawing WITHOUT STORING. Scene only partially refreshable."
345  "\n* Current limit: " << fDisplayListLimit <<
346  ". Change with \"/vis/ogl/set/displayListLimit\"."
347  "\n***************************************************"
348  << G4endl;
349  fMemoryForDisplayLists = false;
350  }
351  }
352 
353  if (pSolid) fSolidMap [pSolid] = fDisplayListId;
354 
355  if (fMemoryForDisplayLists) {
356  if (fReadyForTransients) {
357  TO to(fDisplayListId, fObjectTransformation);
358  if (isPicking) to.fPickName = fPickName;
359  to.fColour = c;
360  const G4VisAttributes* pVA =
361  fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
362  to.fStartTime = pVA->GetStartTime();
363  to.fEndTime = pVA->GetEndTime();
364  to.fMarkerOrPolyline = isMarkerOrPolyline;
365  fTOList.push_back(to);
366  // For transient objects, colour, transformation, are kept in
367  // the TO, so should *not* be in the display list. As mentioned
368  // above, in some cases (display-by-time fading) we need to have
369  // independent control of colour. But for now transform and set
370  // colour for immediate display.
371  glPushMatrix();
372  G4OpenGLTransform3D oglt (fObjectTransformation);
373  glMultMatrixd (oglt.GetGLMatrix ());
374  if (transparency_enabled) {
375  glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
376  } else {
377  glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
378  }
379  (void) ExtraTOProcessing(visible, fTOList.size() - 1);
380  // Ignore return value of the above. If this visible does not use
381  // gl commands, a display list is created that is empty and not
382  // used.
383  glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
384  } else {
385  PO po(fDisplayListId, fObjectTransformation);
386  if (isPicking) po.fPickName = fPickName;
387  po.fColour = c;
388  po.fMarkerOrPolyline = isMarkerOrPolyline;
389  fPOList.push_back(po);
390  // For permanent objects, colour is kept in the PO, so should
391  // *not* be in the display list. This is so that sub-classes
392  // may implement colour modifications according to their own
393  // criteria, e.g., scen tree slider in Qt. But for now set
394  // colour for immediate display.
395  if (transparency_enabled) {
396  glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
397  } else {
398  glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
399  }
400  G4bool usesGLCommands = ExtraPOProcessing(visible, fPOList.size() - 1);
401  // Transients are displayed as they come (GL_COMPILE_AND_EXECUTE
402  // above) but persistents are compiled into display lists
403  // (GL_COMPILE only) and then drawn from the display lists with
404  // their fObjectTransformation as stored in fPOList. Thus,
405  // there is no need to do glMultMatrixd here. If
406  // ExtraPOProcessing says the visible object does not use gl
407  // commands, simply return and abandon further processing. It
408  // is assumed that all relevant information is kept in the
409  // POList.
410  if (!usesGLCommands) return false;
411  glNewList (fDisplayListId, GL_COMPILE);
412  }
413  } else { // Out of memory (or being used when display lists not required).
414  glDrawBuffer (GL_FRONT);
415  glPushMatrix();
416  G4OpenGLTransform3D oglt (fObjectTransformation);
417  glMultMatrixd (oglt.GetGLMatrix ());
418  if (transparency_enabled) {
419  glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
420  } else {
421  glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
422  }
423  }
424 
425  if (fProcessing2D) {
426  // Push current 3D world matrices and load identity to define screen
427  // coordinates...
428  glMatrixMode (GL_PROJECTION);
429  glPushMatrix();
430  glLoadIdentity();
431  glOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
432  glMatrixMode (GL_MODELVIEW);
433  glPushMatrix();
434  glLoadIdentity();
435  G4OpenGLTransform3D oglt (fObjectTransformation);
436  glMultMatrixd (oglt.GetGLMatrix ());
437  glDisable(GL_DEPTH_TEST); // But see parent scene handler!! In
438  glDisable (GL_LIGHTING); // some cases, we need to re-iterate this.
439  }
440 
441  return true;
442 }
443 
444 void G4OpenGLStoredSceneHandler::AddPrimitivePostamble()
445 {
446  if (fProcessing2D) {
447  // Pop current 3D world matrices back again...
448  glMatrixMode (GL_PROJECTION);
449  glPopMatrix();
450  glMatrixMode (GL_MODELVIEW);
451  glPopMatrix();
452  }
453 
454  // if ((glGetError() == GL_TABLE_TOO_LARGE) || (glGetError() == GL_OUT_OF_MEMORY)) { // Could close?
455  if (glGetError() == GL_OUT_OF_MEMORY) { // Could close?
456  G4cout <<
457  "ERROR: G4OpenGLStoredSceneHandler::AddPrimitivePostamble: Failure"
458  " to allocate display List for fTopPODL - try OpenGL Immediated mode."
459  << G4endl;
460  }
461  if (fMemoryForDisplayLists) {
462  glEndList();
463  if (glGetError() == GL_OUT_OF_MEMORY) { // Could close?
464  G4cout <<
465  "ERROR: G4OpenGLStoredSceneHandler::AddPrimitivePostamble: Failure"
466  " to allocate display List for fTopPODL - try OpenGL Immediated mode."
467  << G4endl;
468  }
469  }
470  if (fReadyForTransients || !fMemoryForDisplayLists) {
471  glPopMatrix();
472  }
473 }
474 
475 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline)
476 {
477  G4bool furtherprocessing = AddPrimitivePreamble(polyline);
478  if (furtherprocessing) {
479  G4OpenGLSceneHandler::AddPrimitive(polyline);
480  AddPrimitivePostamble();
481  }
482 }
483 
484 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
485 {
486  G4bool furtherprocessing = AddPrimitivePreamble(polymarker);
487  if (furtherprocessing) {
488  G4OpenGLSceneHandler::AddPrimitive(polymarker);
489  AddPrimitivePostamble();
490  }
491 }
492 
493 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Text& text)
494 {
495  // Note: colour is still handled in
496  // G4OpenGLSceneHandler::AddPrimitive(const G4Text&), so it still
497  // gets into the display list
498  G4bool furtherprocessing = AddPrimitivePreamble(text);
499  if (furtherprocessing) {
500  G4OpenGLSceneHandler::AddPrimitive(text);
501  AddPrimitivePostamble();
502  }
503 }
504 
505 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle)
506 {
507  G4bool furtherprocessing = AddPrimitivePreamble(circle);
508  if (furtherprocessing) {
509  G4OpenGLSceneHandler::AddPrimitive(circle);
510  AddPrimitivePostamble();
511  }
512 }
513 
514 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square)
515 {
516  G4bool furtherprocessing = AddPrimitivePreamble(square);
517  if (furtherprocessing) {
518  G4OpenGLSceneHandler::AddPrimitive(square);
519  AddPrimitivePostamble();
520  }
521 }
522 
523 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Scale& scale)
524 {
525  // Let base class split into primitives.
526  G4OpenGLSceneHandler::AddPrimitive(scale);
527 }
528 
529 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron)
530 {
531  // Note: colour is still handled in
532  // G4OpenGLSceneHandler::AddPrimitive(const G4Polyhedron&), so it still
533  // gets into the display list
534  G4bool furtherprocessing = AddPrimitivePreamble(polyhedron);
535  if (furtherprocessing) {
536  G4OpenGLSceneHandler::AddPrimitive(polyhedron);
537  AddPrimitivePostamble();
538  }
539 }
540 
541 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4NURBS& nurbs)
542 {
543  // Note: colour is still handled in
544  // G4OpenGLSceneHandler::AddPrimitive(const G4NURBS&), so it still
545  // gets into the display list
546  G4bool furtherprocessing = AddPrimitivePreamble(nurbs);
547  if (furtherprocessing) {
548  G4OpenGLSceneHandler::AddPrimitive(nurbs);
549  AddPrimitivePostamble();
550  }
551 }
552 
553 void G4OpenGLStoredSceneHandler::BeginModeling () {
555  /* Debug...
556  fDisplayListId = glGenLists (1);
557  G4cout << "OGL::fDisplayListId (start): " << fDisplayListId << G4endl;
558  */
559 }
560 
561 void G4OpenGLStoredSceneHandler::EndModeling () {
562  // Make a List which calls the other lists.
563  fTopPODL = glGenLists (1);
564  if (glGetError() == GL_OUT_OF_MEMORY) { // Could pre-allocate?
565  G4cout <<
566  "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
567  " display List for fTopPODL - try OpenGL Immediated mode."
568  << G4endl;
569  } else {
570 
571  glNewList (fTopPODL, GL_COMPILE); {
572  for (size_t i = 0; i < fPOList.size (); i++) {
573  glPushMatrix();
574  G4OpenGLTransform3D oglt (fPOList[i].fTransform);
575  glMultMatrixd (oglt.GetGLMatrix ());
576  if (fpViewer->GetViewParameters().IsPicking())
577  glLoadName(fPOList[i].fPickName);
578  glCallList (fPOList[i].fDisplayListId);
579  glPopMatrix();
580  }
581  }
582  glEndList ();
583 
584  if (glGetError() == GL_OUT_OF_MEMORY) { // Could close?
585  G4cout <<
586  "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
587  " display List for fTopPODL - try OpenGL Immediated mode."
588  << G4endl;
589  }
590  }
591 
593 }
594 
595 void G4OpenGLStoredSceneHandler::ClearStore () {
596 
597  //G4cout << "G4OpenGLStoredSceneHandler::ClearStore" << G4endl;
598 
599  G4VSceneHandler::ClearStore (); // Sets need kernel visit, etc.
600 
601  // Delete OpenGL permanent display lists.
602  for (size_t i = 0; i < fPOList.size (); i++)
603  glDeleteLists (fPOList[i].fDisplayListId, 1);
604  if (fTopPODL) glDeleteLists (fTopPODL, 1);
605  fTopPODL = 0;
606 
607  // Clear other lists, dictionary, etc.
608  fPOList.clear ();
609  fSolidMap.clear ();
610  ClearAndDestroyAtts();
611 
612  // ...and clear transient store...
613  for (size_t i = 0; i < fTOList.size (); i++)
614  glDeleteLists(fTOList[i].fDisplayListId, 1);
615  fTOList.clear ();
616 
617  fMemoryForDisplayLists = true;
618 }
619 
620 void G4OpenGLStoredSceneHandler::ClearTransientStore ()
621 {
622  //G4cout << "G4OpenGLStoredSceneHandler::ClearTransientStore" << G4endl;
623 
624  // Delete OpenGL transient display lists and Transient Objects themselves.
625  for (size_t i = 0; i < fTOList.size (); i++)
626  glDeleteLists(fTOList[i].fDisplayListId, 1);
627  fTOList.clear ();
628 
629  fMemoryForDisplayLists = true;
630 
631  // Redraw the scene ready for the next event.
632  if (fpViewer) {
633  fpViewer -> SetView ();
634  fpViewer -> ClearView ();
635  fpViewer -> DrawView ();
636  }
637 }
638 
639 G4int G4OpenGLStoredSceneHandler::fSceneIdCount = 0;
640 
641 G4int G4OpenGLStoredSceneHandler::fDisplayListId = 0;
642 G4bool G4OpenGLStoredSceneHandler::fMemoryForDisplayLists = true;
643 G4int G4OpenGLStoredSceneHandler::fDisplayListLimit = 50000;
644 
645 #endif