source: trunk/source/visualization/OpenGL/src/G4OpenGLStoredSceneHandler.cc @ 944

Last change on this file since 944 was 942, checked in by garnier, 16 years ago

en test

  • Property svn:mime-type set to text/cpp
File size: 18.3 KB
RevLine 
[529]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//
[915]27// $Id: G4OpenGLStoredSceneHandler.cc,v 1.40 2009/02/04 16:48:41 lgarnier Exp $
[877]28// GEANT4 tag $Name:  $
[529]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"
[593]48#include "G4LogicalVolume.hh"
[529]49#include "G4Polyline.hh"
50#include "G4Polymarker.hh"
[593]51#include "G4Text.hh"
[529]52#include "G4Circle.hh"
53#include "G4Square.hh"
[593]54#include "G4Polyhedron.hh"
55#include "G4AttHolder.hh"
[914]56#include "G4OpenGLTransform3D.hh"
57#include "G4OpenGLViewer.hh"
[529]58
[790]59G4OpenGLStoredSceneHandler::PO::PO
60(G4int id,
61 const G4Transform3D& tr):
62  fDisplayListId(id),
63  fTransform(tr),
64  fPickName(0)
65{}
66
67G4OpenGLStoredSceneHandler::TO::TO
68(G4int id,
69 const G4Transform3D& tr):
70  fDisplayListId(id),
71  fTransform(tr),
72  fPickName(0),
73  fStartTime(-DBL_MAX),
74  fEndTime(DBL_MAX)
75{}
76
77G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler
78(G4VGraphicsSystem& system,
79 const G4String& name):
[529]80G4OpenGLSceneHandler (system, fSceneIdCount++, name),
81fMemoryForDisplayLists (true),
82fAddPrimitivePreambleNestingDepth (0),
[936]83fTopPODL (0),
84fLastPolymarker(),
[938]85fLastPolymarkers(),
86nbDoublons(0)
[529]87{}
88
89G4OpenGLStoredSceneHandler::~G4OpenGLStoredSceneHandler ()
90{}
91
92void G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Visible& visible)
93{
94  // Track nesting depth to avoid recursive calls, for example, from a
95  // G4Polymarker that invokes a G4Circle...
96  fAddPrimitivePreambleNestingDepth++;
97  if (fAddPrimitivePreambleNestingDepth > 1) return;
98
[593]99  // Because of our need to control colour of transients (display by
100  // time fading), display lists may only cover a single primitive.
101  // So display list setup is here.
[529]102
[593]103  if (fpViewer->GetViewParameters().IsPicking()) {
104    fPickMap[++fPickName] = 0;
105  }
[529]106
[593]107  const G4Colour& c = GetColour (visible);
[529]108
[593]109  if (fMemoryForDisplayLists) {
110    fDisplayListId = glGenLists (1);
[866]111    if (glGetError() == GL_OUT_OF_MEMORY) {  // Could pre-allocate?
[593]112      G4cout <<
113        "********************* WARNING! ********************"
114        "\nUnable to allocate any more display lists in OpenGL."
115        "\n     Continuing drawing in IMMEDIATE MODE."
116        "\n***************************************************"
117             << G4endl;
118      fMemoryForDisplayLists = false;
119    }
120  }
121  if (fMemoryForDisplayLists) {
122    if (fReadyForTransients) {
123      TO to(fDisplayListId, *fpObjectTransformation);
124      to.fPickName = fPickName;
125      to.fColour = c;
126      const G4VisAttributes* pVA =
127        fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
128      to.fStartTime = pVA->GetStartTime();
129      to.fEndTime = pVA->GetEndTime();
130      fTOList.push_back(to);
131      glDrawBuffer (GL_FRONT);
132      glPushMatrix();
133      G4OpenGLTransform3D oglt (*fpObjectTransformation);
134      glMultMatrixd (oglt.GetGLMatrix ());
135      glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
136      glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
137    }
138    else {
139      PO po(fDisplayListId, *fpObjectTransformation);
140      po.fPickName = fPickName;
141      fPOList.push_back(po);
142      glNewList (fDisplayListId, GL_COMPILE);
143      glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
144    }
[529]145  } else {
[593]146    glDrawBuffer (GL_FRONT);
147    glPushMatrix();
148    G4OpenGLTransform3D oglt (*fpObjectTransformation);
149    glMultMatrixd (oglt.GetGLMatrix ());
[529]150    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
151  }
[593]152
153  if (fProcessing2D) {
154    // Push current 3D world matrices and load identity to define screen
155    // coordinates...
156    glMatrixMode (GL_PROJECTION);
157    glPushMatrix();
158    glLoadIdentity();
[789]159    glOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
[593]160    glMatrixMode (GL_MODELVIEW);
161    glPushMatrix();
162    glLoadIdentity();
[688]163    G4OpenGLTransform3D oglt (*fpObjectTransformation);
164    glMultMatrixd (oglt.GetGLMatrix ());
165    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
[593]166  }
[529]167}
168
169void G4OpenGLStoredSceneHandler::AddPrimitivePostamble()
170{
[593]171  if (fProcessing2D) {
172    // Pop current 3D world matrices back again...
173    glMatrixMode (GL_PROJECTION);
174    glPopMatrix();
175    glMatrixMode (GL_MODELVIEW);
176    glPopMatrix();
177  }
178
[877]179  //  if ((glGetError() == GL_TABLE_TOO_LARGE) || (glGetError() == GL_OUT_OF_MEMORY)) {  // Could close?
180  if (glGetError() == GL_OUT_OF_MEMORY) {  // Could close?
[866]181    G4cout <<
182      "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
183      "  display List for fTopPODL - try OpenGL Immediated mode."
184           << G4endl;
185  }
[593]186  if (fMemoryForDisplayLists) {
187    glEndList();
[866]188    if (glGetError() == GL_OUT_OF_MEMORY) {  // Could close?
189      G4cout <<
190        "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
191        "  display List for fTopPODL - try OpenGL Immediated mode."
192             << G4endl;
193    }
[593]194  }
195  if (fReadyForTransients || !fMemoryForDisplayLists) {
196    glPopMatrix();
197    glFlush ();
198    glDrawBuffer (GL_BACK);
199  }
[529]200  fAddPrimitivePreambleNestingDepth--;
201}
202
203void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline)
204{
205  AddPrimitivePreamble(polyline);
206  G4OpenGLSceneHandler::AddPrimitive(polyline);
207  AddPrimitivePostamble();
208}
209
[593]210void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
211{
[936]212
[938]213  std::vector< G4Polymarker > poly;
[936]214    // 40,83 N03 lancement
215    // 289,69 10Gev supp doublons   + bitmap 21 frame en 10 sec
216    // 343,45 10Gev full polymarker + bitmap 15 frame en 10 sec
217    // 351,67 10Gev full polymarker - bitmap 31 frame en 10 sec
[938]218    // 257,90 10Gev supp doublons MAX  - bitmap 42 frame en 10 sec 45757 markers et 16243 enleves
[936]219  // Check
220  int reste = polymarker.size();
[938]221  bool res = false;
222  if (fLastPolymarkers.size() > 0 ) {
[942]223
224    // Loop new poly to check
[936]225    for (unsigned int b=0; b< polymarker.size();b++) {
[942]226      printf("check %d/%d\n",b,polymarker.size());
[938]227      res= false;
228      for (unsigned int a=0; a< fLastPolymarkers.size() ;a++) {
[942]229        printf("against vect %d/%d\n",a,fLastPolymarker.size());
230        std::vector < G4Polymarker > storedPoly = fLastPolymarkers[a];
231        int size= storedPoly.size()-1;
232        for (unsigned int aPoly=0; aPoly< storedPoly[a].size() ;aPoly++) {
233          printf("against poly %d/%d\n",aPoly,storedPoly.size());
234          if (( storedPoly[size-aPoly].GetPosition().x() == polymarker[b].x()) &&
235              ( storedPoly[size-aPoly].GetPosition().y() == polymarker[b].y()) &&
236              ( storedPoly[size-aPoly].GetPosition().z() == polymarker[b].z())) {
237            reste --;
238            res= true;
239            nbDoublons++;
240            printf("G4OpenGLStoredSceneHandler::AddPrimitive  PT %d/%d ALREADY FOUND TOT:%d. OLD pos %d/%d in %d PolyMarkerList STILL %d Marker in list. Point is %f %f %f\n",b,polymarker.size(),  nbDoublons,  aPoly,storedPoly[a].size(),a   ,reste,polymarker[b].x(),polymarker[b].y(),polymarker[b].z());
241          }
[938]242        }
[936]243      }
[938]244      // Add
245      if (!res) {
246        G4Polymarker tmp;
247        tmp.SetPosition(polymarker[b]);
[942]248        poly.push_back(tmp);
[938]249      }
[936]250    }
[938]251  } else {
252    for (unsigned int b=0; b< polymarker.size();b++) {
253      G4Polymarker tmp;
254      tmp.SetPosition(polymarker[b]);
255      poly.push_back(tmp);
256    }
[936]257  }
[942]258  fLastPolymarkers.push_back(poly);
[936]259#define TEST_MARKER 1
260#ifdef TEST_MARKER
261  // if it is already done
[938]262  if (poly.size() == 1 ) {
263    //   if (polymarker.size() >0) {
264    //     if (( fLastPolymarker.GetPosition().x() == polymarker[0].x()) &&
265    //         ( fLastPolymarker.GetPosition().y() == polymarker[0].y()) &&
266    //         ( fLastPolymarker.GetPosition().z() == polymarker[0].z())) {
267    //       if (fpViewer->GetViewParameters().IsPicking()) {
268    //         glLoadName(++fPickName);
269    //         fPickMap[fPickName] = 0;
270    //       }
271    //       printf("G4OpenGLStoredSceneHandler::AddPrimitive  SUPPR ----------- point %f %f %f\n",polymarker[0].x(),polymarker[0].y(),polymarker[0].z());
272    const G4Colour& c = GetColour (polymarker);
273    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
274    G4OpenGLSceneHandler::AddPrimitive(poly[0]);
275    //    fLastPolymarker.SetPosition(polymarker[poly]);
276    return;
[936]277  }
278#endif 
279  printf("G4OpenGLStoredSceneHandler::AddPrimitive Cree une nouvelle liste de markers\n");
[593]280  AddPrimitivePreamble(polymarker);
281  G4OpenGLSceneHandler::AddPrimitive(polymarker);
282  AddPrimitivePostamble();
[938]283//  fLastPolymarker.SetPosition(polymarker[polymarker.size()-1]);
[593]284}
285
286void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Text& text)
287{
288  // Note: colour is still handled in
289  // G4OpenGLSceneHandler::AddPrimitive(const G4Text&), so it still
290  // gets into the display list
291  AddPrimitivePreamble(text);
292  G4OpenGLSceneHandler::AddPrimitive(text);
293  AddPrimitivePostamble();
294}
295
[529]296void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle)
297{
298  AddPrimitivePreamble(circle);
299  G4OpenGLSceneHandler::AddPrimitive(circle);
300  AddPrimitivePostamble();
301}
302
303void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square)
304{
305  AddPrimitivePreamble(square);
306  G4OpenGLSceneHandler::AddPrimitive(square);
307  AddPrimitivePostamble();
308}
309
[593]310void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Scale& scale)
[529]311{
[593]312  // Let base class split into primitives.
313  G4OpenGLSceneHandler::AddPrimitive(scale);
314}
315
316void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron)
317{
318  // Note: colour is still handled in
319  // G4OpenGLSceneHandler::AddPrimitive(const G4Polyhedron&), so it still
320  // gets into the display list
321  AddPrimitivePreamble(polyhedron);
322  G4OpenGLSceneHandler::AddPrimitive(polyhedron);
[529]323  AddPrimitivePostamble();
324}
325
[593]326void G4OpenGLStoredSceneHandler::AddPrimitive (const G4NURBS& nurbs)
327{
328  // Note: colour is still handled in
329  // G4OpenGLSceneHandler::AddPrimitive(const G4NURBS&), so it still
330  // gets into the display list
331  AddPrimitivePreamble(nurbs);
332  G4OpenGLSceneHandler::AddPrimitive(nurbs);
333  AddPrimitivePostamble();
334}
335
[529]336void G4OpenGLStoredSceneHandler::BeginPrimitives
[593]337(const G4Transform3D& objectTransformation)
338
339  G4OpenGLSceneHandler::BeginPrimitives (objectTransformation);
[529]340
[593]341  // Display list setup moved to AddPrimitivePreamble.  See notes there.
[529]342}
343
[593]344void G4OpenGLStoredSceneHandler::EndPrimitives ()
345{
346  G4OpenGLSceneHandler::EndPrimitives ();
[529]347}
348
[688]349void G4OpenGLStoredSceneHandler::BeginPrimitives2D
350(const G4Transform3D& objectTransformation)
[529]351{
[688]352  G4OpenGLSceneHandler::BeginPrimitives2D(objectTransformation);
[529]353}
354
355void G4OpenGLStoredSceneHandler::EndPrimitives2D ()
356{
[593]357  G4OpenGLSceneHandler::EndPrimitives2D ();
[529]358}
359
360void G4OpenGLStoredSceneHandler::BeginModeling () {
361  G4VSceneHandler::BeginModeling();
362  ClearStore();  // ...and all that goes with it.
363  /* Debug...
364  fDisplayListId = glGenLists (1);
365  G4cout << "OGL::fDisplayListId (start): " << fDisplayListId << G4endl;
366  */
367}
368
369void G4OpenGLStoredSceneHandler::EndModeling () {
370  // Make a List which calls the other lists.
[936]371  printf("G4OpenGLStoredSceneHandler::EndModeling Cree une nouvelle liste+++++++++++++++++++++++++++\n");
[529]372  fTopPODL = glGenLists (1);
[866]373  if (glGetError() == GL_OUT_OF_MEMORY) {  // Could pre-allocate?
[529]374    G4cout <<
375      "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
376      "  display List for fTopPODL - try OpenGL Immediated mode."
377           << G4endl;
[593]378  } else {
[529]379    glNewList (fTopPODL, GL_COMPILE_AND_EXECUTE); {
380      for (size_t i = 0; i < fPOList.size (); i++) {
381        glPushMatrix();
382        G4OpenGLTransform3D oglt (fPOList[i].fTransform);
383        glMultMatrixd (oglt.GetGLMatrix ());
[593]384        if (fpViewer->GetViewParameters().IsPicking())
385          glLoadName(fPOList[i].fPickName);
[529]386        glCallList (fPOList[i].fDisplayListId);
387        glPopMatrix();
388      }
389    }
390    glEndList ();
[866]391    if (glGetError() == GL_OUT_OF_MEMORY) {  // Could close?
392      G4cout <<
393        "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
394        "  display List for fTopPODL - try OpenGL Immediated mode."
395             << G4endl;
396    }
[529]397  }
398
399  G4VSceneHandler::EndModeling ();
400
401  /* Debug...
402  fDisplayListId = glGenLists (1);
403  G4cout << "OGL::fDisplayListId (end): " << fDisplayListId << G4endl;
404  */
405}
406
407void G4OpenGLStoredSceneHandler::ClearStore () {
408
409  G4VSceneHandler::ClearStore ();  // Sets need kernel visit, etc.
410
411  // Delete OpenGL permanent display lists.
412  for (size_t i = 0; i < fPOList.size (); i++)
413    glDeleteLists (fPOList[i].fDisplayListId, 1);
414  if (fTopPODL) glDeleteLists (fTopPODL, 1);
415  fTopPODL = 0;
416
417  // Clear other lists, dictionary, etc.
418  fPOList.clear ();
419  fSolidMap.clear ();
[593]420  ClearAndDestroyAtts();
[529]421
422  // ...and clear transient store...
423  for (size_t i = 0; i < fTOList.size (); i++)
424    glDeleteLists(fTOList[i].fDisplayListId, 1);
425  fTOList.clear ();
426}
427
428void G4OpenGLStoredSceneHandler::ClearTransientStore () {
429
430  G4VSceneHandler::ClearTransientStore ();
431
432  // Delete OpenGL transient display lists and Transient Objects themselves.
433  for (size_t i = 0; i < fTOList.size (); i++)
434    glDeleteLists(fTOList[i].fDisplayListId, 1);
435  fTOList.clear ();
436
437  // Make sure screen corresponds to graphical database...
438  if (fpViewer) {
439    fpViewer -> SetView ();
440    fpViewer -> ClearView ();
441    fpViewer -> DrawView ();
442  }
443}
444
445void G4OpenGLStoredSceneHandler::RequestPrimitives (const G4VSolid& solid)
446{
447  if (fReadyForTransients) {
448    // Always draw transient solids, e.g., hits represented as solids.
449    // (As we have no control over the order of drawing of transient
450    // objects, we cannot do anything about transparent ones, as
451    // below, so always draw them.)
452    G4VSceneHandler::RequestPrimitives (solid);
453    return;
454  }
455
456  // For non-transient (run-duration) objects, ensure transparent
457  // objects are drawn last.  The problem of
458  // blending/transparency/alpha is quite a tricky one - see History
459  // of opengl-V07-01-01/2/3.
460  // Get vis attributes - pick up defaults if none.
461  const G4VisAttributes* pVA =
462    fpViewer -> GetApplicableVisAttributes(fpVisAttribs);
463  const G4Colour& c = pVA -> GetColour ();
464  G4double opacity = c.GetAlpha ();
465
466  if (!fSecondPass) {
467    G4bool transparency_enabled = true;
468    G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
469    if (pViewer) transparency_enabled = pViewer->transparency_enabled;
470    if (transparency_enabled && opacity < 1.) {
471      // On first pass, transparent objects are not drawn, but flag is set...
472      fSecondPassRequested = true;
473      return;
474    }
475  }
476
477  // On second pass, opaque objects are not drwan...
478  if (fSecondPass && opacity >= 1.) return;
479
480  G4PhysicalVolumeModel* pPVModel =
481    dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
482 
483  if (pPVModel) {
484    // If part of the geometry hierarchy, i.e., from a
485    // G4PhysicalVolumeModel, check if a display list already exists for
486    // this solid, re-use it if possible.  We could be smarter, and
487    // recognise repeated branches of the geometry hierarchy, for
488    // example.  But this algorithm should be secure, I think...
489    const G4VSolid* pSolid = &solid;
490    EAxis axis = kRho;
491    G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
492    if (pCurrentPV -> IsReplicated ()) {
493      G4int nReplicas;
494      G4double width;
495      G4double offset;
496      G4bool consuming;
497      pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
498    }
499    // Provided it is not parametrised (because if so, the
500    // solid's parameters might have been changed)...
501    if (!(pCurrentPV -> IsParameterised ()) &&
502        // Provided it is not replicated radially (because if so, the
503        // solid's parameters will have been changed)...
504        !(pCurrentPV -> IsReplicated () && axis == kRho) &&
505        // ...and if the solid has already been rendered...
506        (fSolidMap.find (pSolid) != fSolidMap.end ())) {
507      fDisplayListId = fSolidMap [pSolid];
[593]508      PO po(fDisplayListId,*fpObjectTransformation);
509      if (fpViewer->GetViewParameters().IsPicking()) {
510        G4AttHolder* holder = new G4AttHolder;
511        // Load G4Atts from G4VisAttributes, if any...
512        const G4VisAttributes* va = pPVModel->GetCurrentLV()->GetVisAttributes();
513        if (va) {
514          const std::map<G4String,G4AttDef>* vaDefs = va->GetAttDefs();
515          if (vaDefs) holder->AddAtts(va->CreateAttValues(), vaDefs);
516        }
517        // Load G4Atts from G4PhysicalVolumeModel...
518        const std::map<G4String,G4AttDef>* defs = pPVModel->GetAttDefs();
519        if (defs) holder->AddAtts(pPVModel->CreateCurrentAttValues(), defs);
520        fPickMap[++fPickName] = holder;
521        po.fPickName = fPickName;
522      }
523      fPOList.push_back(po);
[529]524    }
525    else {
526      G4VSceneHandler::RequestPrimitives (solid);
527      fSolidMap [pSolid] = fDisplayListId;
528    }
529    return;
530  }
531
532  // Otherwise invoke base class method...
533  G4VSceneHandler::RequestPrimitives (solid);
534}
535
536G4int G4OpenGLStoredSceneHandler::fSceneIdCount = 0;
537
538#endif
Note: See TracBrowser for help on using the repository browser.