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

Last change on this file since 755 was 754, checked in by garnier, 16 years ago

corrections pour Qt3 mises sous cvs

  • Property svn:mime-type set to text/cpp
File size: 13.9 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.36 2008/02/18 08:53:49 asaim Exp $
28// GEANT4 tag $Name:  $
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 "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
57G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler (G4VGraphicsSystem& system,
58                                          const G4String& name):
59G4OpenGLSceneHandler (system, fSceneIdCount++, name),
60fMemoryForDisplayLists (true),
61fAddPrimitivePreambleNestingDepth (0),
62fTopPODL (0)
63{}
64
65G4OpenGLStoredSceneHandler::~G4OpenGLStoredSceneHandler ()
66{}
67
68void G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Visible& visible)
69{
70  // Track nesting depth to avoid recursive calls, for example, from a
71  // G4Polymarker that invokes a G4Circle...
72  fAddPrimitivePreambleNestingDepth++;
73  if (fAddPrimitivePreambleNestingDepth > 1) return;
74
75  // Because of our need to control colour of transients (display by
76  // time fading), display lists may only cover a single primitive.
77  // So display list setup is here.
78
79  if (fpViewer->GetViewParameters().IsPicking()) {
80    fPickMap[++fPickName] = 0;
81  }
82
83  const G4Colour& c = GetColour (visible);
84
85  if (fMemoryForDisplayLists) {
86    fDisplayListId = glGenLists (1);
87    if (!fDisplayListId) {  // Could pre-allocate?
88      G4cout <<
89        "********************* WARNING! ********************"
90        "\nUnable to allocate any more display lists in OpenGL."
91        "\n     Continuing drawing in IMMEDIATE MODE."
92        "\n***************************************************"
93             << G4endl;
94      fMemoryForDisplayLists = false;
95    }
96  }
97  if (fMemoryForDisplayLists) {
98    if (fReadyForTransients) {
99      TO to(fDisplayListId, *fpObjectTransformation);
100      to.fPickName = fPickName;
101      to.fColour = c;
102      const G4VisAttributes* pVA =
103        fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
104      to.fStartTime = pVA->GetStartTime();
105      to.fEndTime = pVA->GetEndTime();
106      fTOList.push_back(to);
107      glDrawBuffer (GL_FRONT);
108      glPushMatrix();
109      G4OpenGLTransform3D oglt (*fpObjectTransformation);
110      glMultMatrixd (oglt.GetGLMatrix ());
111      glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
112      glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
113    }
114    else {
115      PO po(fDisplayListId, *fpObjectTransformation);
116      po.fPickName = fPickName;
117      fPOList.push_back(po);
118      glNewList (fDisplayListId, GL_COMPILE);
119      glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
120    }
121  } else {
122    glDrawBuffer (GL_FRONT);
123    glPushMatrix();
124    G4OpenGLTransform3D oglt (*fpObjectTransformation);
125    glMultMatrixd (oglt.GetGLMatrix ());
126    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
127  }
128
129  if (fProcessing2D) {
130    // Push current 3D world matrices and load identity to define screen
131    // coordinates...
132    glMatrixMode (GL_PROJECTION);
133    glPushMatrix();
134    glLoadIdentity();
135//    glOrtho (-1., 1., -1., 1., -G4OPENGL_DBL_MAX, G4OPENGL_DBL_MAX);
136    glOrtho (-1., 1., -1., 1., -1., 1.);
137    glMatrixMode (GL_MODELVIEW);
138    glPushMatrix();
139    glLoadIdentity();
140    G4OpenGLTransform3D oglt (*fpObjectTransformation);
141    glMultMatrixd (oglt.GetGLMatrix ());
142    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
143  }
144}
145
146void G4OpenGLStoredSceneHandler::AddPrimitivePostamble()
147{
148  if (fProcessing2D) {
149    // Pop current 3D world matrices back again...
150    glMatrixMode (GL_PROJECTION);
151    glPopMatrix();
152    glMatrixMode (GL_MODELVIEW);
153    glPopMatrix();
154  }
155
156  if (fMemoryForDisplayLists) {
157    glEndList();
158  }
159  if (fReadyForTransients || !fMemoryForDisplayLists) {
160    glPopMatrix();
161    glFlush ();
162    glDrawBuffer (GL_BACK);
163  }
164  fAddPrimitivePreambleNestingDepth--;
165}
166
167void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline)
168{
169  AddPrimitivePreamble(polyline);
170  G4OpenGLSceneHandler::AddPrimitive(polyline);
171  AddPrimitivePostamble();
172}
173
174void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
175{
176  AddPrimitivePreamble(polymarker);
177  G4OpenGLSceneHandler::AddPrimitive(polymarker);
178  AddPrimitivePostamble();
179}
180
181void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Text& text)
182{
183  // Note: colour is still handled in
184  // G4OpenGLSceneHandler::AddPrimitive(const G4Text&), so it still
185  // gets into the display list
186  AddPrimitivePreamble(text);
187  G4OpenGLSceneHandler::AddPrimitive(text);
188  AddPrimitivePostamble();
189}
190
191void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle)
192{
193  AddPrimitivePreamble(circle);
194  G4OpenGLSceneHandler::AddPrimitive(circle);
195  AddPrimitivePostamble();
196}
197
198void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square)
199{
200  AddPrimitivePreamble(square);
201  G4OpenGLSceneHandler::AddPrimitive(square);
202  AddPrimitivePostamble();
203}
204
205void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Scale& scale)
206{
207  // Let base class split into primitives.
208  G4OpenGLSceneHandler::AddPrimitive(scale);
209}
210
211void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron)
212{
213  // Note: colour is still handled in
214  // G4OpenGLSceneHandler::AddPrimitive(const G4Polyhedron&), so it still
215  // gets into the display list
216  AddPrimitivePreamble(polyhedron);
217  G4OpenGLSceneHandler::AddPrimitive(polyhedron);
218  AddPrimitivePostamble();
219}
220
221void G4OpenGLStoredSceneHandler::AddPrimitive (const G4NURBS& nurbs)
222{
223  // Note: colour is still handled in
224  // G4OpenGLSceneHandler::AddPrimitive(const G4NURBS&), so it still
225  // gets into the display list
226  AddPrimitivePreamble(nurbs);
227  G4OpenGLSceneHandler::AddPrimitive(nurbs);
228  AddPrimitivePostamble();
229}
230
231void G4OpenGLStoredSceneHandler::BeginPrimitives
232(const G4Transform3D& objectTransformation)
233
234  G4OpenGLSceneHandler::BeginPrimitives (objectTransformation);
235
236  // Display list setup moved to AddPrimitivePreamble.  See notes there.
237}
238
239void G4OpenGLStoredSceneHandler::EndPrimitives ()
240{
241  G4OpenGLSceneHandler::EndPrimitives ();
242}
243
244void G4OpenGLStoredSceneHandler::BeginPrimitives2D
245(const G4Transform3D& objectTransformation)
246{
247  G4OpenGLSceneHandler::BeginPrimitives2D(objectTransformation);
248}
249
250void G4OpenGLStoredSceneHandler::EndPrimitives2D ()
251{
252  G4OpenGLSceneHandler::EndPrimitives2D ();
253}
254
255void G4OpenGLStoredSceneHandler::BeginModeling () {
256  G4VSceneHandler::BeginModeling();
257  ClearStore();  // ...and all that goes with it.
258  /* Debug...
259  fDisplayListId = glGenLists (1);
260  G4cout << "OGL::fDisplayListId (start): " << fDisplayListId << G4endl;
261  */
262}
263
264void G4OpenGLStoredSceneHandler::EndModeling () {
265  // Make a List which calls the other lists.
266  fTopPODL = glGenLists (1);
267  if (!fTopPODL) {
268    G4cout <<
269      "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
270      "  display List for fTopPODL - try OpenGL Immediated mode."
271           << G4endl;
272  } else {
273    glNewList (fTopPODL, GL_COMPILE_AND_EXECUTE); {
274      for (size_t i = 0; i < fPOList.size (); i++) {
275        glPushMatrix();
276        G4OpenGLTransform3D oglt (fPOList[i].fTransform);
277        glMultMatrixd (oglt.GetGLMatrix ());
278        if (fpViewer->GetViewParameters().IsPicking())
279          glLoadName(fPOList[i].fPickName);
280        glCallList (fPOList[i].fDisplayListId);
281        glPopMatrix();
282      }
283    }
284    glEndList ();
285  }
286
287  G4VSceneHandler::EndModeling ();
288
289  /* Debug...
290  fDisplayListId = glGenLists (1);
291  G4cout << "OGL::fDisplayListId (end): " << fDisplayListId << G4endl;
292  */
293}
294
295void G4OpenGLStoredSceneHandler::ClearStore () {
296
297  G4VSceneHandler::ClearStore ();  // Sets need kernel visit, etc.
298
299  // Delete OpenGL permanent display lists.
300  for (size_t i = 0; i < fPOList.size (); i++)
301    glDeleteLists (fPOList[i].fDisplayListId, 1);
302  if (fTopPODL) glDeleteLists (fTopPODL, 1);
303  fTopPODL = 0;
304
305  // Clear other lists, dictionary, etc.
306  fPOList.clear ();
307  fSolidMap.clear ();
308  ClearAndDestroyAtts();
309
310  // ...and clear transient store...
311  for (size_t i = 0; i < fTOList.size (); i++)
312    glDeleteLists(fTOList[i].fDisplayListId, 1);
313  fTOList.clear ();
314}
315
316void G4OpenGLStoredSceneHandler::ClearTransientStore () {
317
318  G4VSceneHandler::ClearTransientStore ();
319
320  // Delete OpenGL transient display lists and Transient Objects themselves.
321  for (size_t i = 0; i < fTOList.size (); i++)
322    glDeleteLists(fTOList[i].fDisplayListId, 1);
323  fTOList.clear ();
324
325  // Make sure screen corresponds to graphical database...
326  if (fpViewer) {
327    fpViewer -> SetView ();
328    fpViewer -> ClearView ();
329    fpViewer -> DrawView ();
330  }
331}
332
333void G4OpenGLStoredSceneHandler::RequestPrimitives (const G4VSolid& solid)
334{
335  if (fReadyForTransients) {
336    // Always draw transient solids, e.g., hits represented as solids.
337    // (As we have no control over the order of drawing of transient
338    // objects, we cannot do anything about transparent ones, as
339    // below, so always draw them.)
340    G4VSceneHandler::RequestPrimitives (solid);
341    return;
342  }
343
344  // For non-transient (run-duration) objects, ensure transparent
345  // objects are drawn last.  The problem of
346  // blending/transparency/alpha is quite a tricky one - see History
347  // of opengl-V07-01-01/2/3.
348  // Get vis attributes - pick up defaults if none.
349  const G4VisAttributes* pVA =
350    fpViewer -> GetApplicableVisAttributes(fpVisAttribs);
351  const G4Colour& c = pVA -> GetColour ();
352  G4double opacity = c.GetAlpha ();
353
354  if (!fSecondPass) {
355    G4bool transparency_enabled = true;
356    G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
357    if (pViewer) transparency_enabled = pViewer->transparency_enabled;
358    if (transparency_enabled && opacity < 1.) {
359      // On first pass, transparent objects are not drawn, but flag is set...
360      fSecondPassRequested = true;
361      return;
362    }
363  }
364
365  // On second pass, opaque objects are not drwan...
366  if (fSecondPass && opacity >= 1.) return;
367
368  G4PhysicalVolumeModel* pPVModel =
369    dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
370 
371  if (pPVModel) {
372    // If part of the geometry hierarchy, i.e., from a
373    // G4PhysicalVolumeModel, check if a display list already exists for
374    // this solid, re-use it if possible.  We could be smarter, and
375    // recognise repeated branches of the geometry hierarchy, for
376    // example.  But this algorithm should be secure, I think...
377    const G4VSolid* pSolid = &solid;
378    EAxis axis = kRho;
379    G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
380    if (pCurrentPV -> IsReplicated ()) {
381      G4int nReplicas;
382      G4double width;
383      G4double offset;
384      G4bool consuming;
385      pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
386    }
387    // Provided it is not parametrised (because if so, the
388    // solid's parameters might have been changed)...
389    if (!(pCurrentPV -> IsParameterised ()) &&
390        // Provided it is not replicated radially (because if so, the
391        // solid's parameters will have been changed)...
392        !(pCurrentPV -> IsReplicated () && axis == kRho) &&
393        // ...and if the solid has already been rendered...
394        (fSolidMap.find (pSolid) != fSolidMap.end ())) {
395      fDisplayListId = fSolidMap [pSolid];
396      PO po(fDisplayListId,*fpObjectTransformation);
397      if (fpViewer->GetViewParameters().IsPicking()) {
398        G4AttHolder* holder = new G4AttHolder;
399        // Load G4Atts from G4VisAttributes, if any...
400        const G4VisAttributes* va = pPVModel->GetCurrentLV()->GetVisAttributes();
401        if (va) {
402          const std::map<G4String,G4AttDef>* vaDefs = va->GetAttDefs();
403          if (vaDefs) holder->AddAtts(va->CreateAttValues(), vaDefs);
404        }
405        // Load G4Atts from G4PhysicalVolumeModel...
406        const std::map<G4String,G4AttDef>* defs = pPVModel->GetAttDefs();
407        if (defs) holder->AddAtts(pPVModel->CreateCurrentAttValues(), defs);
408        fPickMap[++fPickName] = holder;
409        po.fPickName = fPickName;
410      }
411      fPOList.push_back(po);
412    }
413    else {
414      G4VSceneHandler::RequestPrimitives (solid);
415      fSolidMap [pSolid] = fDisplayListId;
416    }
417    return;
418  }
419
420  // Otherwise invoke base class method...
421  G4VSceneHandler::RequestPrimitives (solid);
422}
423
424G4int G4OpenGLStoredSceneHandler::fSceneIdCount = 0;
425
426#endif
Note: See TracBrowser for help on using the repository browser.