source: trunk/geant4/visualization/OpenGL/src/G4OpenGLStoredSceneHandler.cc @ 553

Last change on this file since 553 was 529, checked in by garnier, 17 years ago

r658@mac-90108: laurentgarnier | 2007-06-25 12:02:16 +0200
import de visualisation

  • Property svn:mime-type set to text/cpp
File size: 12.6 KB
Line 
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: G4OpenGLStoredSceneHandler.cc,v 1.31 2006/08/30 11:43:57 allison Exp $
28// GEANT4 tag $Name: geant4-08-02-patch-01 $
29//
30//
31// Andrew Walkden  10th February 1997
32// OpenGL stored scene - creates OpenGL display lists.
33
34#ifdef G4VIS_BUILD_OPENGL_DRIVER
35
36// Included here - problems with HP compiler if not before other includes?
37#include "G4NURBS.hh"
38
39// Here follows a special for Mesa, the OpenGL emulator.  Does not affect
40// other OpenGL's, as far as I'm aware.   John Allison 18/9/96.
41#define CENTERLINE_CLPP  /* CenterLine C++ workaround: */
42// Also seems to be required for HP's CC and AIX xlC, at least.
43
44#include "G4OpenGLStoredSceneHandler.hh"
45
46#include "G4PhysicalVolumeModel.hh"
47#include "G4VPhysicalVolume.hh"
48#include "G4Polyline.hh"
49#include "G4Polymarker.hh"
50#include "G4Circle.hh"
51#include "G4Square.hh"
52
53G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler (G4VGraphicsSystem& system,
54                                          const G4String& name):
55G4OpenGLSceneHandler (system, fSceneIdCount++, name),
56fMemoryForDisplayLists (true),
57fAddPrimitivePreambleNestingDepth (0),
58fTopPODL (0)
59{}
60
61G4OpenGLStoredSceneHandler::~G4OpenGLStoredSceneHandler ()
62{}
63
64void G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Visible& visible)
65{
66  // Track nesting depth to avoid recursive calls, for example, from a
67  // G4Polymarker that invokes a G4Circle...
68  fAddPrimitivePreambleNestingDepth++;
69  if (fAddPrimitivePreambleNestingDepth > 1) return;
70
71  const G4Colour& c = GetColour (visible);
72
73  if (fMemoryForDisplayLists && fReadyForTransients) {
74
75    TO& to = fTOList.back();  // Transient object information.
76
77    // Get vis attributes - pick up defaults if none.
78    const G4VisAttributes* pVA =
79      fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
80
81    // Get time information from vis attributes.
82    to.fStartTime = pVA->GetStartTime();
83    to.fEndTime = pVA->GetEndTime();
84
85    // Keep colour out of (already started) display list so that it
86    // can be applied independently.
87    glEndList();
88    glDeleteLists(fDisplayListId, 1);
89    to.fColour = c;
90    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
91    glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
92     
93  } else {
94
95    // Make sure colour is set in other cases.
96    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
97  }
98}
99
100void G4OpenGLStoredSceneHandler::AddPrimitivePostamble()
101{
102  fAddPrimitivePreambleNestingDepth--;
103}
104
105void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline)
106{
107  AddPrimitivePreamble(polyline);
108  G4OpenGLSceneHandler::AddPrimitive(polyline);
109  AddPrimitivePostamble();
110}
111
112void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle)
113{
114  AddPrimitivePreamble(circle);
115  G4OpenGLSceneHandler::AddPrimitive(circle);
116  AddPrimitivePostamble();
117}
118
119void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square)
120{
121  AddPrimitivePreamble(square);
122  G4OpenGLSceneHandler::AddPrimitive(square);
123  AddPrimitivePostamble();
124}
125
126void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
127{
128  AddPrimitivePreamble(polymarker);
129  G4OpenGLSceneHandler::AddPrimitive(polymarker);
130  AddPrimitivePostamble();
131}
132
133void G4OpenGLStoredSceneHandler::BeginPrimitives
134(const G4Transform3D& objectTransformation) {
135 
136  G4VSceneHandler::BeginPrimitives (objectTransformation);
137
138  if (fMemoryForDisplayLists) {
139    fDisplayListId = glGenLists (1);
140    if (!fDisplayListId) {  // Could pre-allocate?
141      G4cout << "********************* WARNING! ********************\n"
142           <<"Unable to allocate any more display lists in OpenGL.\n "
143           << "      Continuing drawing in IMMEDIATE MODE.\n"
144           << "***************************************************" << G4endl;
145      fMemoryForDisplayLists = false;
146    }
147  }
148  if (fMemoryForDisplayLists) {
149    if (fReadyForTransients) {
150      TO to(fDisplayListId, objectTransformation);
151      fTOList.push_back(to);
152      glDrawBuffer (GL_FRONT);
153      glPushMatrix();
154      G4OpenGLTransform3D oglt (objectTransformation);
155      glMultMatrixd (oglt.GetGLMatrix ());
156      glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
157    }
158    else {
159      fPOList.push_back(PO(fDisplayListId, objectTransformation));
160      glNewList (fDisplayListId, GL_COMPILE);
161    }
162  } else {
163    glDrawBuffer (GL_FRONT);
164    glPushMatrix();
165    G4OpenGLTransform3D oglt (objectTransformation);
166    glMultMatrixd (oglt.GetGLMatrix ());
167  }
168}
169
170void G4OpenGLStoredSceneHandler::EndPrimitives () {
171  if (fMemoryForDisplayLists) {
172    glEndList();
173  }
174  if (fReadyForTransients || !fMemoryForDisplayLists) {
175    glPopMatrix();
176    glFlush ();
177    glDrawBuffer (GL_BACK);
178  }
179  G4VSceneHandler::EndPrimitives ();
180}
181
182void G4OpenGLStoredSceneHandler::BeginPrimitives2D()
183{
184  G4VSceneHandler::BeginPrimitives2D();
185
186  if (fMemoryForDisplayLists) {
187    fDisplayListId = glGenLists (1);
188    if (!fDisplayListId) {  // Could pre-allocate?
189      G4cout << "********************* WARNING! ********************\n"
190           <<"Unable to allocate any more display lists in OpenGL.\n "
191           << "      Continuing drawing in IMMEDIATE MODE.\n"
192           << "***************************************************" << G4endl;
193      fMemoryForDisplayLists = false;
194    }
195  }
196  if (fMemoryForDisplayLists) {
197    if (fReadyForTransients) {
198      fTOList.push_back(TO(fDisplayListId));
199      glDrawBuffer (GL_FRONT);
200      glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
201    }
202    else {
203      fPOList.push_back(PO(fDisplayListId));
204      glNewList (fDisplayListId, GL_COMPILE);
205    }
206  } else {
207    glDrawBuffer (GL_FRONT);
208  }
209  // Push current 3D world matrices and load identity to define screen
210  // coordinates...
211  glMatrixMode (GL_PROJECTION);
212  glPushMatrix();
213  glLoadIdentity();
214  glOrtho (-1., 1., -1., 1., -DBL_MAX, DBL_MAX);
215  glMatrixMode (GL_MODELVIEW);
216  glPushMatrix();
217  glLoadIdentity();
218}
219
220void G4OpenGLStoredSceneHandler::EndPrimitives2D ()
221{
222  // Pop current 3D world matrices back again...
223  glMatrixMode (GL_PROJECTION);
224  glPopMatrix();
225  glMatrixMode (GL_MODELVIEW);
226  glPopMatrix();
227
228  if (fMemoryForDisplayLists) {
229    glEndList();
230  }
231  if (fReadyForTransients || !fMemoryForDisplayLists) {
232    glFlush ();
233    glDrawBuffer (GL_BACK);
234  }
235  G4VSceneHandler::EndPrimitives2D ();
236}
237
238void G4OpenGLStoredSceneHandler::BeginModeling () {
239  G4VSceneHandler::BeginModeling();
240  ClearStore();  // ...and all that goes with it.
241  /* Debug...
242  fDisplayListId = glGenLists (1);
243  G4cout << "OGL::fDisplayListId (start): " << fDisplayListId << G4endl;
244  */
245}
246
247void G4OpenGLStoredSceneHandler::EndModeling () {
248  // Make a List which calls the other lists.
249  fTopPODL = glGenLists (1);
250  if (!fTopPODL) {
251    G4cout <<
252      "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
253      "  display List for fTopPODL - try OpenGL Immediated mode."
254           << G4endl;
255  }
256  else {
257    glNewList (fTopPODL, GL_COMPILE_AND_EXECUTE); {
258      for (size_t i = 0; i < fPOList.size (); i++) {
259        glPushMatrix();
260        G4OpenGLTransform3D oglt (fPOList[i].fTransform);
261        glMultMatrixd (oglt.GetGLMatrix ());
262        glCallList (fPOList[i].fDisplayListId);
263        glPopMatrix();
264      }
265    }
266    glEndList ();
267  }
268
269  G4VSceneHandler::EndModeling ();
270
271  /* Debug...
272  fDisplayListId = glGenLists (1);
273  G4cout << "OGL::fDisplayListId (end): " << fDisplayListId << G4endl;
274  */
275}
276
277void G4OpenGLStoredSceneHandler::ClearStore () {
278
279  G4VSceneHandler::ClearStore ();  // Sets need kernel visit, etc.
280
281  // Delete OpenGL permanent display lists.
282  for (size_t i = 0; i < fPOList.size (); i++)
283    glDeleteLists (fPOList[i].fDisplayListId, 1);
284  if (fTopPODL) glDeleteLists (fTopPODL, 1);
285  fTopPODL = 0;
286
287  // Clear other lists, dictionary, etc.
288  fPOList.clear ();
289  fSolidMap.clear ();
290
291  // ...and clear transient store...
292  for (size_t i = 0; i < fTOList.size (); i++)
293    glDeleteLists(fTOList[i].fDisplayListId, 1);
294  fTOList.clear ();
295}
296
297void G4OpenGLStoredSceneHandler::ClearTransientStore () {
298
299  G4VSceneHandler::ClearTransientStore ();
300
301  // Delete OpenGL transient display lists and Transient Objects themselves.
302  for (size_t i = 0; i < fTOList.size (); i++)
303    glDeleteLists(fTOList[i].fDisplayListId, 1);
304  fTOList.clear ();
305
306  // Make sure screen corresponds to graphical database...
307  if (fpViewer) {
308    fpViewer -> SetView ();
309    fpViewer -> ClearView ();
310    fpViewer -> DrawView ();
311  }
312}
313
314void G4OpenGLStoredSceneHandler::RequestPrimitives (const G4VSolid& solid)
315{
316  if (fReadyForTransients) {
317    // Always draw transient solids, e.g., hits represented as solids.
318    // (As we have no control over the order of drawing of transient
319    // objects, we cannot do anything about transparent ones, as
320    // below, so always draw them.)
321    G4VSceneHandler::RequestPrimitives (solid);
322    return;
323  }
324
325  // For non-transient (run-duration) objects, ensure transparent
326  // objects are drawn last.  The problem of
327  // blending/transparency/alpha is quite a tricky one - see History
328  // of opengl-V07-01-01/2/3.
329  // Get vis attributes - pick up defaults if none.
330  const G4VisAttributes* pVA =
331    fpViewer -> GetApplicableVisAttributes(fpVisAttribs);
332  const G4Colour& c = pVA -> GetColour ();
333  G4double opacity = c.GetAlpha ();
334
335  if (!fSecondPass) {
336    G4bool transparency_enabled = true;
337    G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
338    if (pViewer) transparency_enabled = pViewer->transparency_enabled;
339    if (transparency_enabled && opacity < 1.) {
340      // On first pass, transparent objects are not drawn, but flag is set...
341      fSecondPassRequested = true;
342      return;
343    }
344  }
345
346  // On second pass, opaque objects are not drwan...
347  if (fSecondPass && opacity >= 1.) return;
348
349  G4PhysicalVolumeModel* pPVModel =
350    dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
351 
352  if (pPVModel) {
353    // If part of the geometry hierarchy, i.e., from a
354    // G4PhysicalVolumeModel, check if a display list already exists for
355    // this solid, re-use it if possible.  We could be smarter, and
356    // recognise repeated branches of the geometry hierarchy, for
357    // example.  But this algorithm should be secure, I think...
358    const G4VSolid* pSolid = &solid;
359    EAxis axis = kRho;
360    G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
361    if (pCurrentPV -> IsReplicated ()) {
362      G4int nReplicas;
363      G4double width;
364      G4double offset;
365      G4bool consuming;
366      pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
367    }
368    // Provided it is not parametrised (because if so, the
369    // solid's parameters might have been changed)...
370    if (!(pCurrentPV -> IsParameterised ()) &&
371        // Provided it is not replicated radially (because if so, the
372        // solid's parameters will have been changed)...
373        !(pCurrentPV -> IsReplicated () && axis == kRho) &&
374        // ...and if the solid has already been rendered...
375        (fSolidMap.find (pSolid) != fSolidMap.end ())) {
376      fDisplayListId = fSolidMap [pSolid];
377      fPOList.push_back(PO(fDisplayListId,*fpObjectTransformation));
378    }
379    else {
380      G4VSceneHandler::RequestPrimitives (solid);
381      fSolidMap [pSolid] = fDisplayListId;
382    }
383    return;
384  }
385
386  // Otherwise invoke base class method...
387  G4VSceneHandler::RequestPrimitives (solid);
388}
389
390G4int G4OpenGLStoredSceneHandler::fSceneIdCount = 0;
391
392#endif
Note: See TracBrowser for help on using the repository browser.