Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/OpenGL/src/G4OpenGLStoredSceneHandler.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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  10th February 1997
 30 // OpenGL stored scene - creates OpenGL display lists.
 31 
 32 #include "G4OpenGLStoredSceneHandler.hh"
 33 
 34 #include "G4PhysicalVolumeModel.hh"
 35 #include "G4LogicalVolumeModel.hh"
 36 #include "G4VPhysicalVolume.hh"
 37 #include "G4LogicalVolume.hh"
 38 #include "G4Polyline.hh"
 39 #include "G4Polymarker.hh"
 40 #include "G4Text.hh"
 41 #include "G4Circle.hh"
 42 #include "G4Square.hh"
 43 #include "G4Polyhedron.hh"
 44 #include "G4AttHolder.hh"
 45 #include "G4OpenGLTransform3D.hh"
 46 #include "G4OpenGLViewer.hh"
 47 #include "G4AttHolder.hh"
 48 
 49 #include <typeinfo>
 50 
 51 G4int G4OpenGLStoredSceneHandler::fSceneIdCount = 0;
 52 
 53 G4int  G4OpenGLStoredSceneHandler::fDisplayListId = 0;
 54 
 55 G4OpenGLStoredSceneHandler::PO::PO():
 56   fDisplayListId(0),
 57   fPickName(0),
 58   fpG4TextPlus(0),
 59   fMarkerOrPolyline(false)
 60 {}
 61 
 62 G4OpenGLStoredSceneHandler::PO::PO(const G4OpenGLStoredSceneHandler::PO& po):
 63   fDisplayListId(po.fDisplayListId),
 64   fTransform(po.fTransform),
 65   fPickName(po.fPickName),
 66   fColour(po.fColour),
 67   fpG4TextPlus(po.fpG4TextPlus? new G4TextPlus(*po.fpG4TextPlus): 0),
 68   fMarkerOrPolyline(po.fMarkerOrPolyline)
 69 {}
 70 
 71 G4OpenGLStoredSceneHandler::PO::PO(G4int id, const G4Transform3D& tr):
 72   fDisplayListId(id),
 73   fTransform(tr),
 74   fPickName(0),
 75   fpG4TextPlus(0),
 76   fMarkerOrPolyline(false)
 77 {}
 78 
 79 G4OpenGLStoredSceneHandler::PO::~PO()
 80 {
 81   delete fpG4TextPlus;
 82 }
 83 
 84 G4OpenGLStoredSceneHandler::PO& G4OpenGLStoredSceneHandler::PO::operator=
 85   (const G4OpenGLStoredSceneHandler::PO& rhs)
 86 {
 87   if (&rhs == this) return *this;
 88   fDisplayListId = rhs.fDisplayListId;
 89   fTransform = rhs.fTransform;
 90   fPickName = rhs.fPickName;
 91   fColour = rhs.fColour;
 92   fpG4TextPlus = rhs.fpG4TextPlus? new G4TextPlus(*rhs.fpG4TextPlus): 0;
 93   fMarkerOrPolyline = rhs.fMarkerOrPolyline;
 94   return *this;
 95 }
 96 
 97 G4OpenGLStoredSceneHandler::TO::TO():
 98   fDisplayListId(0),
 99   fPickName(0),
100   fStartTime(-G4VisAttributes::fVeryLongTime),
101   fEndTime(G4VisAttributes::fVeryLongTime),
102   fpG4TextPlus(0),
103   fMarkerOrPolyline(false)
104 {}
105 
106 G4OpenGLStoredSceneHandler::TO::TO(const G4OpenGLStoredSceneHandler::TO& to):
107   fDisplayListId(to.fDisplayListId),
108   fTransform(to.fTransform),
109   fPickName(to.fPickName),
110   fStartTime(to.fStartTime),
111   fEndTime(to.fEndTime),
112   fColour(to.fColour),
113   fpG4TextPlus(to.fpG4TextPlus? new G4TextPlus(*to.fpG4TextPlus): 0),
114   fMarkerOrPolyline(to.fMarkerOrPolyline)
115 {}
116 
117 G4OpenGLStoredSceneHandler::TO::TO(G4int id, const G4Transform3D& tr):
118   fDisplayListId(id),
119   fTransform(tr),
120   fPickName(0),
121   fStartTime(-G4VisAttributes::fVeryLongTime),
122   fEndTime(G4VisAttributes::fVeryLongTime),
123   fpG4TextPlus(0),
124   fMarkerOrPolyline(false)
125 {}
126 
127 G4OpenGLStoredSceneHandler::TO::~TO()
128 {
129   delete fpG4TextPlus;
130 }
131 
132 G4OpenGLStoredSceneHandler::TO& G4OpenGLStoredSceneHandler::TO::operator=
133   (const G4OpenGLStoredSceneHandler::TO& rhs)
134 {
135   if (&rhs == this) return *this;
136   fDisplayListId = rhs.fDisplayListId;
137   fTransform = rhs.fTransform;
138   fPickName = rhs.fPickName;
139   fStartTime = rhs.fStartTime;
140   fEndTime = rhs.fEndTime;
141   fColour = rhs.fColour;
142   fpG4TextPlus = rhs.fpG4TextPlus? new G4TextPlus(*rhs.fpG4TextPlus): 0;
143   fMarkerOrPolyline = rhs.fMarkerOrPolyline;
144   return *this;
145 }
146 
147 G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler
148 (G4VGraphicsSystem& system,
149  const G4String& name):
150 G4OpenGLSceneHandler (system, fSceneIdCount++, name),
151 fDoNotUseDisplayList(false),
152 fTopPODL (0)
153 {}
154 
155 G4OpenGLStoredSceneHandler::~G4OpenGLStoredSceneHandler ()
156 {}
157 
158 void G4OpenGLStoredSceneHandler::BeginPrimitives
159 (const G4Transform3D& objectTransformation)
160 {  
161   G4OpenGLSceneHandler::BeginPrimitives (objectTransformation);
162   if (fReadyForTransients) glDrawBuffer (GL_FRONT);
163   // Display list setup moved to AddPrimitivePreamble.  See notes there.
164 }
165 
166 void G4OpenGLStoredSceneHandler::EndPrimitives ()
167 {
168   // See all primitives immediately...  At least soon...
169   ScaledFlush();
170   glDrawBuffer (GL_BACK);
171   G4OpenGLSceneHandler::EndPrimitives ();
172 }
173 
174 void G4OpenGLStoredSceneHandler::BeginPrimitives2D
175 (const G4Transform3D& objectTransformation)
176 {
177   G4OpenGLSceneHandler::BeginPrimitives2D(objectTransformation);
178   if (fReadyForTransients) glDrawBuffer (GL_FRONT);
179 }
180 
181 void G4OpenGLStoredSceneHandler::EndPrimitives2D ()
182 {
183   // See all primitives immediately...  At least soon...
184   ScaledFlush();
185   glDrawBuffer (GL_BACK);
186   G4OpenGLSceneHandler::EndPrimitives2D ();
187 }
188 
189 G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4VMarker& visible)
190 {
191   return AddPrimitivePreambleInternal(visible, true, false);
192 }
193 G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Polyline& visible)
194 {
195   return AddPrimitivePreambleInternal(visible, false, true);
196 }
197 G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Polyhedron& visible)
198 {
199   return AddPrimitivePreambleInternal(visible, false, false);
200 }
201 
202 G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreambleInternal
203 (const G4Visible& visible, bool isMarker, bool isPolyline)
204 {
205 // Get applicable vis attributes for all primitives.
206   fpVisAttribs = fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
207   const G4Colour& c = GetColour ();
208   G4double opacity = c.GetAlpha ();
209 
210   G4bool transparency_enabled = true;
211   G4bool isMarkerNotHidden = true;
212   G4OpenGLViewer* pOGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
213   if (pOGLViewer) {
214     transparency_enabled = pOGLViewer->transparency_enabled;
215     isMarkerNotHidden = pOGLViewer->fVP.IsMarkerNotHidden();
216   }
217   
218   G4bool isTransparent = opacity < 1.;
219   G4bool isMarkerOrPolyline = isMarker || isPolyline;
220   G4bool treatAsTransparent = transparency_enabled && isTransparent;
221   G4bool treatAsNotHidden = isMarkerNotHidden && isMarkerOrPolyline;
222   
223   if (fProcessing2D) glDisable (GL_DEPTH_TEST);
224   else {
225     if (isMarkerOrPolyline && isMarkerNotHidden)
226       glDisable (GL_DEPTH_TEST);
227     else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);}
228   }
229 
230   if (fThreePassCapable) {
231     
232     // Ensure transparent objects are drawn *after* opaque ones and before
233     // non-hidden markers.  The problem of blending/transparency/alpha
234     // is quite a tricky one - see History of opengl-V07-01-01/2/3.
235     if (!(fSecondPassForTransparency || fThirdPassForNonHiddenMarkers)) {
236       // First pass...
237       if (treatAsTransparent) {  // Request pass for transparent objects...
238         fSecondPassForTransparencyRequested = true;
239       }
240       if (treatAsNotHidden) {    // Request pass for non-hidden markers...
241         fThirdPassForNonHiddenMarkersRequested = true;
242       }
243       // On first pass, transparent objects and non-hidden markers are not drawn...
244       if (treatAsTransparent || treatAsNotHidden) {
245         return false;  // No further processing.
246       }
247     }
248     
249     // On second pass, only transparent objects are drawn...
250     if (fSecondPassForTransparency) {
251       if (!treatAsTransparent) {
252         return false;  // No further processing.
253       }
254     }
255     
256     // On third pass, only non-hidden markers are drawn...
257     if (fThirdPassForNonHiddenMarkers) {
258       if (!treatAsNotHidden) {
259         return false;  // No further processing.
260       }
261     }
262   }  // fThreePassCapable
263   
264   // Loads G4Atts for picking...
265   G4bool isPicking = false;
266   if (fpViewer->GetViewParameters().IsPicking()) {
267     isPicking = true;
268     glLoadName(++fPickName);
269     G4AttHolder* holder = new G4AttHolder;
270     LoadAtts(visible, holder);
271     fPickMap[fPickName] = holder;
272   }
273 
274   // Because of our need to control colour of transients (display by
275   // time fading), display lists may only cover a single primitive.
276   // So display list setup is here.
277 
278   if (fDoNotUseDisplayList) {
279 
280     glPushMatrix();
281     G4OpenGLTransform3D oglt (fObjectTransformation);
282     glMultMatrixd (oglt.GetGLMatrix ());
283     if (transparency_enabled) {
284       glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
285     } else {
286       glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
287     }
288 
289   } else {
290 
291     fDisplayListId = glGenLists (1);
292     if (glGetError() == GL_OUT_OF_MEMORY) {
293       static G4int errorCount = 0;
294       if (errorCount < 5) {
295         errorCount++;
296         G4ExceptionDescription ed;
297         ed <<
298         "Error attempting to create an OpenGL display list."
299         "\nCurrent display list id: " << fDisplayListId <<
300         "\nMaybe out of memory?";
301         G4Exception
302         ("G4OpenGLStoredSceneHandler::AddPrimitivePreambleInternal","opengl1001",
303          JustWarning,ed);
304       }
305       return false;
306     }
307     if (fReadyForTransients) {
308       TO to(fDisplayListId, fObjectTransformation);
309       if (isPicking) to.fPickName = fPickName;
310       to.fColour = c;
311       to.fStartTime = fpVisAttribs->GetStartTime();
312       to.fEndTime = fpVisAttribs->GetEndTime();
313       to.fMarkerOrPolyline = isMarkerOrPolyline;
314       fTOList.push_back(to);
315       // For transient objects, colour, transformation, are kept in
316       // the TO, so should *not* be in the display list.  As mentioned
317       // above, in some cases (display-by-time fading) we need to have
318       // independent control of colour.  But for now transform and set
319       // colour for immediate display.
320       glPushMatrix();
321       G4OpenGLTransform3D oglt (fObjectTransformation);
322       glMultMatrixd (oglt.GetGLMatrix ());
323       if (transparency_enabled) {
324         glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
325       } else {
326         glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
327       }
328       (void) ExtraTOProcessing(visible, fTOList.size() - 1);
329       // Ignore return value of the above.  If this visible does not use
330       // gl commands, a display list is created that is empty and not
331       // used.
332       glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
333     } else {
334       PO po(fDisplayListId, fObjectTransformation);
335       if (isPicking) po.fPickName = fPickName;
336       po.fColour = c;
337       po.fMarkerOrPolyline = isMarkerOrPolyline;
338       fPOList.push_back(po);
339       // For permanent objects, colour is kept in the PO, so should
340       // *not* be in the display list.  This is so that sub-classes
341       // may implement colour modifications according to their own
342       // criteria, e.g., scene tree slider in Qt.  But for now set
343       // colour for immediate display.
344       if (transparency_enabled) {
345         glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
346       } else {
347         glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
348       }
349       G4bool usesGLCommands = ExtraPOProcessing(visible, fPOList.size() - 1);
350       // Transients are displayed as they come (GL_COMPILE_AND_EXECUTE
351       // above) but persistents are compiled into display lists
352       // (GL_COMPILE only) and then drawn from the display lists with
353       // their fObjectTransformation as stored in fPOList.  Thus,
354       // there is no need to do glMultMatrixd here.  If
355       // ExtraPOProcessing says the visible object does not use gl
356       // commands, simply return and abandon further processing.  It
357       // is assumed that all relevant information is kept in the
358       // POList.
359       if (!usesGLCommands) return false;
360       glNewList (fDisplayListId, GL_COMPILE);
361     }
362   }
363 
364   if (fProcessing2D) {
365     // Push current 3D world matrices and load identity to define screen
366     // coordinates...
367     glMatrixMode (GL_PROJECTION);
368     glPushMatrix();
369     glLoadIdentity();
370     if (pOGLViewer) {
371       pOGLViewer->g4GlOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
372     }
373     glMatrixMode (GL_MODELVIEW);
374     glPushMatrix();
375     glLoadIdentity();
376     G4OpenGLTransform3D oglt (fObjectTransformation);
377     glMultMatrixd (oglt.GetGLMatrix ());
378     glDisable (GL_LIGHTING);
379   } else {
380     if (isMarker) {
381       glDisable (GL_LIGHTING);
382     } else {
383       glEnable (GL_LIGHTING);
384     }
385   }
386 
387   return true;
388 }
389 
390 void G4OpenGLStoredSceneHandler::AddPrimitivePostamble()
391 {
392   if (fProcessing2D) {
393     // Pop current 3D world matrices back again...
394     glMatrixMode (GL_PROJECTION);
395     glPopMatrix();
396     glMatrixMode (GL_MODELVIEW);
397     glPopMatrix();
398   }
399 
400   //  if ((glGetError() == GL_TABLE_TOO_LARGE) || (glGetError() == GL_OUT_OF_MEMORY)) {  // Could close?
401   if (glGetError() == GL_OUT_OF_MEMORY) {  // Could close?
402     G4cerr <<
403       "ERROR: G4OpenGLStoredSceneHandler::AddPrimitivePostamble: Failure"
404       "  to allocate display List for fTopPODL - try OpenGL Immediated mode."
405            << G4endl;
406   }
407   if (!fDoNotUseDisplayList) {
408     glEndList();
409     if (glGetError() == GL_OUT_OF_MEMORY) {  // Could close?
410       G4cerr <<
411         "ERROR: G4OpenGLStoredSceneHandler::AddPrimitivePostamble: Failure"
412   "  to allocate display List for fTopPODL - try OpenGL Immediated mode."
413              << G4endl;
414     }
415   }
416   if (fReadyForTransients || fDoNotUseDisplayList) {
417     glPopMatrix();
418   }
419 }
420 
421 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline)
422 {
423   G4bool furtherprocessing = AddPrimitivePreamble(polyline);
424   if (furtherprocessing) {
425     G4OpenGLSceneHandler::AddPrimitive(polyline);
426     AddPrimitivePostamble();
427   }
428 }
429 
430 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
431 {
432   G4bool furtherprocessing = AddPrimitivePreamble(polymarker);
433   if (furtherprocessing) {
434     G4OpenGLSceneHandler::AddPrimitive(polymarker);
435     AddPrimitivePostamble();
436   }
437 }
438 
439 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Text& text)
440 {
441   // Note: colour is still handled in
442   // G4OpenGLSceneHandler::AddPrimitive(const G4Text&), so it still
443   // gets into the display list
444   G4bool furtherprocessing = AddPrimitivePreamble(text);
445   if (furtherprocessing) {
446     G4OpenGLSceneHandler::AddPrimitive(text);
447     AddPrimitivePostamble();
448   }
449 }
450 
451 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle)
452 {
453   G4bool furtherprocessing = AddPrimitivePreamble(circle);
454   if (furtherprocessing) {
455     G4OpenGLSceneHandler::AddPrimitive(circle);
456     AddPrimitivePostamble();
457   }
458 }
459 
460 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square)
461 {
462   G4bool furtherprocessing = AddPrimitivePreamble(square);
463   if (furtherprocessing) {
464     G4OpenGLSceneHandler::AddPrimitive(square);
465     AddPrimitivePostamble();
466   }
467 }
468 
469 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron)
470 {
471   // Note: colour is still handled in
472   // G4OpenGLSceneHandler::AddPrimitive(const G4Polyhedron&), so it still
473   // gets into the display list
474   G4bool furtherprocessing = AddPrimitivePreamble(polyhedron);
475   if (furtherprocessing) {
476     G4OpenGLSceneHandler::AddPrimitive(polyhedron);
477     AddPrimitivePostamble();
478   }
479 }
480 
481 void G4OpenGLStoredSceneHandler::BeginModeling () {
482   G4VSceneHandler::BeginModeling();
483   /* Debug...
484   fDisplayListId = glGenLists (1);
485   G4cout << "OGL::fDisplayListId (start): " << fDisplayListId << G4endl;
486   */
487 }
488 
489 void G4OpenGLStoredSceneHandler::EndModeling () {
490   // Make a List which calls the other lists.
491   fTopPODL = glGenLists (1);
492   if (glGetError() == GL_OUT_OF_MEMORY) {  // Could pre-allocate?
493     G4cerr <<
494       "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
495       "  display List for fTopPODL - try OpenGL Immediated mode."
496      << G4endl;
497   } else {
498 
499     glNewList (fTopPODL, GL_COMPILE); {
500       for (size_t i = 0; i < fPOList.size (); i++) {
501   glPushMatrix();
502   G4OpenGLTransform3D oglt (fPOList[i].fTransform);
503   glMultMatrixd (oglt.GetGLMatrix ());
504   if (fpViewer->GetViewParameters().IsPicking())
505     glLoadName(fPOList[i].fPickName);
506   glCallList (fPOList[i].fDisplayListId);
507   glPopMatrix();
508       }
509     }
510     glEndList ();
511 
512     if (glGetError() == GL_OUT_OF_MEMORY) {  // Could close?
513       G4cerr <<
514         "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
515         "  display List for fTopPODL - try OpenGL Immediated mode."
516              << G4endl;
517     }
518   }
519 
520   G4VSceneHandler::EndModeling ();
521 }
522 
523 void G4OpenGLStoredSceneHandler::ClearStore () {
524 
525   //G4cout << "G4OpenGLStoredSceneHandler::ClearStore" << G4endl;
526 
527   G4VSceneHandler::ClearStore ();  // Sets need kernel visit, etc.
528 
529   // Delete OpenGL permanent display lists.
530   for (size_t i = 0; i < fPOList.size (); i++)
531     glDeleteLists (fPOList[i].fDisplayListId, 1);
532   if (fTopPODL) glDeleteLists (fTopPODL, 1);
533   fTopPODL = 0;
534 
535   // Clear other lists, dictionary, etc.
536   fPOList.clear ();
537   fSolidMap.clear ();
538   ClearAndDestroyAtts();
539 
540   // ...and clear transient store...
541   for (size_t i = 0; i < fTOList.size (); i++)
542     glDeleteLists(fTOList[i].fDisplayListId, 1);
543   fTOList.clear ();
544 }
545 
546 void G4OpenGLStoredSceneHandler::ClearTransientStore ()
547 {
548   //G4cout << "G4OpenGLStoredSceneHandler::ClearTransientStore" << G4endl;
549 
550   // Delete OpenGL transient display lists and Transient Objects themselves.
551   for (size_t i = 0; i < fTOList.size (); i++)
552     glDeleteLists(fTOList[i].fDisplayListId, 1);
553   fTOList.clear ();
554 
555   // Redraw the scene ready for the next event.
556   if (fpViewer) {
557     fpViewer -> SetView ();
558     fpViewer -> ClearView ();
559     fpViewer -> DrawView ();
560   }
561 }
562