source: trunk/source/visualization/OpenGL/src/G4OpenGLSceneHandler.cc @ 1114

Last change on this file since 1114 was 1113, checked in by garnier, 15 years ago

en debug.....

  • Property svn:mime-type set to text/cpp
File size: 29.1 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//
[935]27// $Id: G4OpenGLSceneHandler.cc,v 1.55 2009/03/03 14:51:29 lgarnier Exp $
[877]28// GEANT4 tag $Name:  $
[529]29//
30//
31// Andrew Walkden  27th March 1996
32// OpenGL stored scene - creates OpenGL display lists.
33// OpenGL immediate scene - draws immediately to buffer
34//                           (saving space on server).
35
36#ifdef G4VIS_BUILD_OPENGL_DRIVER
37
38// Included here - problems with HP compiler if not before other includes?
39#include "G4NURBS.hh"
40
41// Here follows a special for Mesa, the OpenGL emulator.  Does not affect
42// other OpenGL's, as far as I'm aware.   John Allison 18/9/96.
43#define CENTERLINE_CLPP  /* CenterLine C++ workaround: */
44// Also seems to be required for HP's CC and AIX xlC, at least.
45
[1113]46
47// FIXME : L.Garnier 22 Sept 09
48// This include should be the first, because we should include
49// qobject.h first. I don't know why, but on macOSX 10.5.8, if
50// we do not, it says :
51// /Library/Frameworks/QtCore.framework/Headers/qglobal.h:1895: error: redefinition of ‘class QTypeInfo<char>’
52// /Library/Frameworks/QtCore.framework/Headers/qglobal.h:1894: error: previous definition of ‘class QTypeInfo<char>’
53
54#include "G4OpenGLQtViewer.hh"
[529]55#include "G4OpenGLSceneHandler.hh"
56#include "G4OpenGLViewer.hh"
57#include "G4OpenGLFontBaseStore.hh"
58#include "G4OpenGLTransform3D.hh"
59#include "G4Point3D.hh"
60#include "G4Normal3D.hh"
61#include "G4Transform3D.hh"
62#include "G4Polyline.hh"
[593]63#include "G4Polymarker.hh"
[529]64#include "G4Text.hh"
65#include "G4Circle.hh"
66#include "G4Square.hh"
67#include "G4VMarker.hh"
68#include "G4Polyhedron.hh"
69#include "G4VisAttributes.hh"
70#include "G4PhysicalVolumeModel.hh"
71#include "G4VPhysicalVolume.hh"
72#include "G4LogicalVolume.hh"
73#include "G4VSolid.hh"
74#include "G4Scene.hh"
75#include "G4VisExtent.hh"
[593]76#include "G4AttHolder.hh"
[529]77
78G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4VGraphicsSystem& system,
79                              G4int id,
80                              const G4String& name):
[593]81  G4VSceneHandler (system, id, name),
82  fPickName(0),
[688]83  fProcessing2D (false),
[593]84  fProcessingPolymarker(false)
[1049]85{
86#ifdef G4DEBUG_VIS_OGL
87  printf("INIT G4OpenGLSceneHandler (after G4OpenGLSceneHandler G4VSceneHandler (system, id, name)\n");
88#endif
89}
[529]90
91G4OpenGLSceneHandler::~G4OpenGLSceneHandler ()
92{
93  ClearStore ();
94}
95
96const GLubyte G4OpenGLSceneHandler::fStippleMaskHashed [128] = {
97  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
98  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
99  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
100  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
101  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
102  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
103  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
104  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
105  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
106  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
107  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
108  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
109  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
110  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
111  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
112  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
113};
114
[593]115void G4OpenGLSceneHandler::ClearAndDestroyAtts()
116{
117  std::map<GLuint, G4AttHolder*>::iterator i;
118  for (i = fPickMap.begin(); i != fPickMap.end(); ++i) delete i->second;
119  fPickMap.clear();
120}
121
122void G4OpenGLSceneHandler::PreAddSolid
123(const G4Transform3D& objectTransformation,
124 const G4VisAttributes& visAttribs)
125{
126  G4VSceneHandler::PreAddSolid (objectTransformation, visAttribs);
127}
128
129void G4OpenGLSceneHandler::BeginPrimitives
130(const G4Transform3D& objectTransformation)
131{
132  G4VSceneHandler::BeginPrimitives (objectTransformation);
133}
134
135void G4OpenGLSceneHandler::EndPrimitives ()
136{
137  G4VSceneHandler::EndPrimitives ();
138}
139
[688]140void G4OpenGLSceneHandler::BeginPrimitives2D
141(const G4Transform3D& objectTransformation)
[593]142{
[688]143  G4VSceneHandler::BeginPrimitives2D (objectTransformation);
144  fProcessing2D = true;
[593]145}
146
147void G4OpenGLSceneHandler::EndPrimitives2D ()
148{
[688]149  fProcessing2D = false;
[593]150  G4VSceneHandler::EndPrimitives2D ();
151}
152
[529]153const G4Polyhedron* G4OpenGLSceneHandler::CreateSectionPolyhedron ()
154{
155  // Clipping done in G4OpenGLViewer::SetView.
156  return 0;
157
158  // But...OpenGL no longer seems to reconstruct clipped edges, so,
159  // when the BooleanProcessor is up to it, abandon this and use
160  // generic clipping in G4VSceneHandler::CreateSectionPolyhedron...
161  // return G4VSceneHandler::CreateSectionPolyhedron();
162}
163
164const G4Polyhedron* G4OpenGLSceneHandler::CreateCutawayPolyhedron ()
165{
166  // Cutaway done in G4OpenGLViewer::SetView.
167  return 0;
168
169  // But...if not, when the BooleanProcessor is up to it...
170  // return G4VSceneHandler::CreateCutawayPolyhedron();
171}
172
173void G4OpenGLSceneHandler::AddPrimitive (const G4Polyline& line)
174{
175  G4int nPoints = line.size ();
176  if (nPoints <= 0) return;
177
[593]178  // Loads G4Atts for picking...
179  if (fpViewer->GetViewParameters().IsPicking()) {
180    G4AttHolder* holder = new G4AttHolder;
181    LoadAtts(line, holder);
182    fPickMap[fPickName] = holder;
183  }
184
[529]185  // Note: colour treated in sub-class.
186
187  if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ())
188    glDisable (GL_DEPTH_TEST);
189  else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS);}
190
191  glDisable (GL_LIGHTING);
192
[593]193  // Get vis attributes - pick up defaults if none.
194  const G4VisAttributes* pVA =
195    fpViewer -> GetApplicableVisAttributes (line.GetVisAttributes ());
196
197  G4double lineWidth = GetLineWidth(pVA);
[529]198  glLineWidth(lineWidth);
199
200  glBegin (GL_LINE_STRIP);
201  for (G4int iPoint = 0; iPoint < nPoints; iPoint++) {
202  G4double x, y, z;
203    x = line[iPoint].x();
204    y = line[iPoint].y();
205    z = line[iPoint].z();
206    glVertex3d (x, y, z);
207  }
208  glEnd ();
209}
210
[593]211void G4OpenGLSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
212{
213  G4int nPoints = polymarker.size ();
214  if (nPoints <= 0) return;
215
216  fProcessingPolymarker = true;
217
218  // Loads G4Atts for picking...
219  if (fpViewer->GetViewParameters().IsPicking()) {
220    G4AttHolder* holder = new G4AttHolder;
221    LoadAtts(polymarker, holder);
222    fPickMap[fPickName] = holder;
223  }
224
225  switch (polymarker.GetMarkerType()) {
226  default:
227  case G4Polymarker::dots:
228    {
229      for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
230        G4Circle dot (polymarker);
231        dot.SetPosition (polymarker[iPoint]);
232        dot.SetWorldSize  (0.);
233        dot.SetScreenSize (0.1);  // Very small circle.
234        G4OpenGLSceneHandler::AddPrimitive (dot);
235      }
236    }
237    break;
238  case G4Polymarker::circles:
239    {
240      for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
241        G4Circle circle (polymarker);
242        circle.SetPosition (polymarker[iPoint]);
243        G4OpenGLSceneHandler::AddPrimitive (circle);
244      }
245    }
246    break;
247  case G4Polymarker::squares:
248    {
249      for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
250        G4Square square (polymarker);
251        square.SetPosition (polymarker[iPoint]);
252        G4OpenGLSceneHandler::AddPrimitive (square);
253      }
254    }
255    break;
256  }
257
258  fProcessingPolymarker = false;
259}
260
[529]261void G4OpenGLSceneHandler::AddPrimitive (const G4Text& text) {
262
[1113]263#ifdef G4DEBUG_VIS_OGL
264  printf ("G4OpenGLSceneHandler::AddPrimitives TEXT\n");
265#endif 
[593]266  // Loads G4Atts for picking...
267  if (fpViewer->GetViewParameters().IsPicking()) {
[1113]268#ifdef G4DEBUG_VIS_OGL
269  printf ("G4OpenGLSceneHandler::AddPrimitives PICKING\n");
270#endif 
[593]271    G4AttHolder* holder = new G4AttHolder;
272    LoadAtts(text, holder);
273    fPickMap[fPickName] = holder;
274  }
275
[529]276  const G4Colour& c = GetTextColour (text);  // Picks up default if none.
277  MarkerSizeType sizeType;
278  G4double size = GetMarkerSize (text, sizeType);
279  G4ThreeVector position (text.GetPosition ());
280  G4String textString = text.GetText();
281
[1113]282#ifdef G4DEBUG_VIS_OGL
283  printf ("G4OpenGLSceneHandler::AddPrimitives TEXT -%s-X:%f Y:%f Z:%f- - Red:%f Green:%f Blue:%f--\n",textString.c_str(),position.x(),position.y(),position.z(),c.GetRed (), c.GetGreen (), c.GetBlue ());
284#endif 
285
[529]286  G4int font_base = G4OpenGLFontBaseStore::GetFontBase(fpViewer,size);
[1113]287#ifdef G4DEBUG_VIS_OGL
288  printf ("G4OpenGLSceneHandler::AddPrimitives getFontBase ?size=%f-recu:%d-\n",size,font_base);
289#endif 
[529]290  if (font_base < 0) {
[1113]291#ifdef G4DEBUG_VIS_OGL
292    printf ("G4OpenGLSceneHandler::AddPrimitives NO FONT BASE--\n");
293#endif 
294   
295#ifdef G4DEBUG_VIS_OGL
296    printf ("G4OpenGLSceneHandler::AddPrimitives SPECIAL CASE\n");
297#endif 
298    G4OpenGLQtViewer* oGLSQtViewer = dynamic_cast<G4OpenGLQtViewer*>(fpViewer);
299    if (oGLSQtViewer) {
300      // FIXME : No font for the moment
301      const char* textCString = textString.c_str();
302      oGLSQtViewer->drawText(textCString,position.x(),position.y(),position.z(),size);
303    }
[529]304    static G4int callCount = 0;
305    ++callCount;
306    if (callCount <= 10 || callCount%100 == 0) {
[1113]307     
308     
309     
[529]310      G4cout <<
311        "G4OpenGLSceneHandler::AddPrimitive (const G4Text&) call count "
312             << callCount <<
313        "\n  No fonts available."
314        "\n  Called with text \""
315             << text.GetText ()
316             << "\"\n  at " << position
317             << ", size " << size
318             << ", offsets " << text.GetXOffset () << ", " << text.GetYOffset ()
319             << ", type " << G4int(sizeType)
320             << ", colour " << c
321             << G4endl;
322    }
323    return;
324  }
325  const char* textCString = textString.c_str();
326  glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
[1113]327  G4OpenGLQtViewer* oGLSQtViewer = dynamic_cast<G4OpenGLQtViewer*>(fpViewer);
328
329  if (oGLSQtViewer) {
330    // FIXME : No font for the moment
331    oGLSQtViewer->drawText(textCString,position.x(),position.y(),position.z(),size);
332  } else {
333    glDisable (GL_DEPTH_TEST);
334    glDisable (GL_LIGHTING);
335   
336    glRasterPos3d(position.x(),position.y(),position.z());
337    // No action on offset or layout at present.
338    glPushAttrib(GL_LIST_BIT);
339    glListBase(font_base);
340    glCallLists(strlen(textCString), GL_UNSIGNED_BYTE, (GLubyte *)textCString);
341    glPopAttrib();
342  }
343  //     //////////////
344  //     makeCurrent();
345  //     glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT);
346  //     glRasterPos3d(x, y, z);
347  //     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
348  //     glEnable(GL_BLEND);
349  //     glListBase(fontDisplayListBase(fnt, listBase));
350  //     glCallLists(str.length(), GL_UNSIGNED_BYTE, str.local8Bit());
351  //     glPopAttrib();
352  //     //////////////
[529]353 
[1113]354#ifdef G4DEBUG_VIS_OGL
355  printf ("G4OpenGLSceneHandler::AddPrimitives TEXT\n");
356#endif 
[529]357}
358
359void G4OpenGLSceneHandler::AddPrimitive (const G4Circle& circle) {
360  glEnable (GL_POINT_SMOOTH);
[593]361  AddCircleSquare (circle, G4OpenGLBitMapStore::circle);
[529]362}
363
364void G4OpenGLSceneHandler::AddPrimitive (const G4Square& square) {
365  glDisable (GL_POINT_SMOOTH);
[593]366  AddCircleSquare (square, G4OpenGLBitMapStore::square);
[529]367}
368
369void G4OpenGLSceneHandler::AddCircleSquare
370(const G4VMarker& marker,
[593]371 G4OpenGLBitMapStore::Shape shape) {
[529]372
[593]373  if (!fProcessingPolymarker) {  // Polymarker has already loaded atts.
374    // Loads G4Atts for picking...
375    if (fpViewer->GetViewParameters().IsPicking()) {
376      G4AttHolder* holder = new G4AttHolder;
377      LoadAtts(marker, holder);
378      fPickMap[fPickName] = holder;
379    }
380  }
381
[529]382  // Note: colour treated in sub-class.
383
384  if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ())
385    glDisable (GL_DEPTH_TEST);
386  else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS);}
387 
388  glDisable (GL_LIGHTING);
389 
[593]390  // Get vis attributes - pick up defaults if none.
391  const G4VisAttributes* pVA =
392    fpViewer -> GetApplicableVisAttributes (marker.GetVisAttributes ());
393
394  G4double lineWidth = GetLineWidth(pVA);
[529]395  glLineWidth(lineWidth);
396
397  G4VMarker::FillStyle style = marker.GetFillStyle();
[593]398
399  G4bool filled = false;
400  static G4bool hashedWarned = false;
[529]401 
402  switch (style) {
403  case G4VMarker::noFill:
404    glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
[593]405    filled = false;
[529]406    break;
407   
408  case G4VMarker::hashed:
[593]409    if (!hashedWarned) {
410      G4cout << "Hashed fill style in G4OpenGLSceneHandler."
411             << "\n  Not implemented.  Using G4VMarker::filled."
412             << G4endl;
413      hashedWarned = true;
414    }
415    // Maybe use
416    //glPolygonStipple (fStippleMaskHashed);
417    // Drop through to filled...
[529]418   
419  case G4VMarker::filled:
420    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
[593]421    filled = true;
[529]422    break;
423   
424  }
425
426  // A few useful quantities...
427  G4Point3D centre = marker.GetPosition();
428  MarkerSizeType sizeType;
429  G4double size = GetMarkerSize(marker, sizeType);
430
[593]431  // Draw...
[931]432   if (sizeType == world) {  // Size specified in world coordinates.
[935]433
[931]434     DrawXYPolygon (shape, size, centre, pVA);
[529]435
[931]436   } else { // Size specified in screen (window) coordinates.
[1009]437     glPointSize (size);       
[933]438     glBegin (GL_POINTS);
439     glVertex3f(centre.x(),centre.y(),centre.z());
440     glEnd();
441     //Antialiasing
442     glEnable (GL_POINT_SMOOTH);
443     //Transparency
444     glEnable(GL_BLEND);
445     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
[935]446
447     // L. GARNIER 1 March 2009
448     // Old method, we draw a bitmap instead of a GL_POINT.
449     // I remove it because it cost in term of computing performances
450     // and gl2ps can't draw bitmaps
451
452     //      glRasterPos3d(centre.x(),centre.y(),centre.z());
453     //      const GLubyte* marker =
454     //        G4OpenGLBitMapStore::GetBitMap(shape, size, filled);
455     //      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
456     //      glBitmap(GLsizei(size), GLsizei(size), size/2., size/2., 0., 0., marker);
[931]457   }
[529]458}
459
[593]460void G4OpenGLSceneHandler::DrawXYPolygon
461(G4OpenGLBitMapStore::Shape shape,
462 G4double size,
[529]463 const G4Point3D& centre,
[593]464 const G4VisAttributes* pApplicableVisAtts)
465{
466  G4int nSides;
467  G4double startPhi;
468  if (shape == G4OpenGLBitMapStore::circle) {
469    nSides = GetNoOfSides(pApplicableVisAtts);
470    startPhi = 0.;
471  } else {
472    nSides = 4;
473    startPhi = -pi / 4.;
[529]474  }
475
476  const G4Vector3D& viewpointDirection =
477    fpViewer -> GetViewParameters().GetViewpointDirection();
478  const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector();
479  const G4double dPhi = twopi / nSides;
480  const G4double radius = size / 2.;
481  G4Vector3D start = radius * (up.cross(viewpointDirection)).unit();
482  G4double phi;
483  G4int i;
[593]484
[529]485  glBegin (GL_POLYGON);
[593]486  for (i = 0, phi = startPhi; i < nSides; i++, phi += dPhi) {
[529]487    G4Vector3D r = start; r.rotate(phi, viewpointDirection);
488    G4Vector3D p = centre + r;
489    glVertex3d (p.x(), p.y(), p.z());
490  }
491  glEnd ();
492}
493
[593]494void G4OpenGLSceneHandler::AddPrimitive (const G4Scale& scale)
495{
496  G4VSceneHandler::AddPrimitive(scale);
497}
498
[529]499//Method for handling G4Polyhedron objects for drawing solids.
500void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
501  // Assume all facets are planar convex quadrilaterals.
502  // Draw each facet individually
[1113]503#ifdef G4DEBUG_VIS_OGL
504  printf ("G4OpenGLSceneHandler::AddPrimitives BEGIN poly\n");
505#endif 
[529]506  if (polyhedron.GetNoFacets() == 0) return;
[1113]507#ifdef G4DEBUG_VIS_OGL
508    printf ("G4OpenGLSceneHandler::AddPrimitives BEGIN 2 poly %d ++ %d\n",fpViewer,fpViewer->GetViewParameters().IsPicking());
509#endif
[529]510
[593]511  // Loads G4Atts for picking...
512  if (fpViewer->GetViewParameters().IsPicking()) {
513    G4AttHolder* holder = new G4AttHolder;
[1036]514    const G4Visible vis;
[1113]515#ifdef G4DEBUG_VIS_OGL
516    printf ("G4OpenGLSceneHandler::AddPrimitives poly %d\n",&polyhedron);
517#endif
518    LoadAtts(polyhedron, holder);
[1036]519    //    LoadAtts(polyhedron, holder);
[593]520    fPickMap[fPickName] = holder;
521  }
522
[529]523  // Get vis attributes - pick up defaults if none.
524  const G4VisAttributes* pVA =
525    fpViewer -> GetApplicableVisAttributes (polyhedron.GetVisAttributes ());
526
527  // Get view parameters that the user can force through the vis
528  // attributes, thereby over-riding the current view parameter.
529  G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
530
531  //Get colour, etc...
532  G4bool transparency_enabled = true;
533  G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
534  if (pViewer) transparency_enabled = pViewer->transparency_enabled;
[593]535  const G4Colour& c = pVA->GetColour();
[529]536  GLfloat materialColour [4];
537  materialColour [0] = c.GetRed ();
538  materialColour [1] = c.GetGreen ();
539  materialColour [2] = c.GetBlue ();
540  if (transparency_enabled) {
541    materialColour [3] = c.GetAlpha ();
542  } else {
543    materialColour [3] = 1.;
544  }
545
[593]546  G4double lineWidth = GetLineWidth(pVA);
[529]547  glLineWidth(lineWidth);
548
549  GLfloat clear_colour[4];
550  glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour);
551
552  G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
553
554  G4bool clipping = pViewer->fVP.IsSection() || pViewer->fVP.IsCutaway();
555
[754]556  // Lighting disabled unless otherwise requested
557  glDisable (GL_LIGHTING);
558
[529]559  switch (drawing_style) {
560  case (G4ViewParameters::hlhsr):
561    // Set up as for hidden line removal but paint polygon faces later...
562  case (G4ViewParameters::hlr):
563    glEnable (GL_STENCIL_TEST);
564    // The stencil buffer is cleared in G4OpenGLViewer::ClearView.
565    // The procedure below leaves it clear.
566    glStencilFunc (GL_ALWAYS, 0, 1);
567    glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
568    glEnable (GL_DEPTH_TEST);
569    glDepthFunc (GL_LEQUAL);
570    if (materialColour[3] < 1.) {
571      // Transparent...
572      glDisable (GL_CULL_FACE);
573      glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
574    } else {
575      // Opaque...
576      if (clipping) {
577        glDisable (GL_CULL_FACE);
578        glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
579      } else {
580        glEnable (GL_CULL_FACE);
581        glCullFace (GL_BACK);
582        glPolygonMode (GL_FRONT, GL_LINE);
583      }
584    }
585    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
586    break;
587  case (G4ViewParameters::hsr):
588    glEnable (GL_DEPTH_TEST);
589    glDepthFunc (GL_LEQUAL);   
590    if (materialColour[3] < 1.) {
591      // Transparent...
592      glDepthMask (0);  // Make depth buffer read-only.
593      glDisable (GL_CULL_FACE);
594      glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
595      glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, materialColour);
596    } else {
597      // Opaque...
598      glDepthMask (1);  // Make depth buffer writable (default).
599      if (clipping) {
600        glDisable (GL_CULL_FACE);
601        glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
602      } else {
603        glEnable (GL_CULL_FACE);
604        glCullFace (GL_BACK);
605        glPolygonMode (GL_FRONT, GL_FILL);
606      }
607      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
608    }
[688]609    if (!fProcessing2D) glEnable (GL_LIGHTING);
[529]610    break;
611  case (G4ViewParameters::wireframe):
612  default:
613    glEnable (GL_DEPTH_TEST);
614    glDepthFunc (GL_LEQUAL);    //??? was GL_ALWAYS
615    glDisable (GL_CULL_FACE);
616    glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
617    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
618    break;
619  }
620
621  //Loop through all the facets...
622  glBegin (GL_QUADS);
623  G4bool notLastFace;
624  do {
625
626    //First, find vertices, edgeflags and normals and note "not last facet"...
627    G4Point3D vertex[4];
628    G4int edgeFlag[4];
629    G4Normal3D normals[4];
630    G4int n;
631    notLastFace = polyhedron.GetNextFacet(n, vertex, edgeFlag, normals);
632
633    //Loop through the four edges of each G4Facet...
634    G4int edgeCount = 0;
635    for(edgeCount = 0; edgeCount < n; ++edgeCount) {
636      // Check to see if edge is visible or not...
637      if (isAuxEdgeVisible) {
638        edgeFlag[edgeCount] = 1;
639      }
640      if (edgeFlag[edgeCount] > 0) {
641        glEdgeFlag (GL_TRUE);
642      } else {
643        glEdgeFlag (GL_FALSE);
644      }
645      glNormal3d (normals[edgeCount].x(),
646                  normals[edgeCount].y(),
647                  normals[edgeCount].z());
648      glVertex3d (vertex[edgeCount].x(),
649                  vertex[edgeCount].y(),
650                  vertex[edgeCount].z());
651    }
652    // HepPolyhedron produces triangles too; in that case add an extra
653    // vertex identical to first...
654    if (n == 3) {
655      edgeCount = 3;
656      normals[edgeCount] = normals[0];
657      vertex[edgeCount] = vertex[0];
658      edgeFlag[edgeCount] = -1;
659      glEdgeFlag (GL_FALSE);
660      glNormal3d (normals[edgeCount].x(),
661                  normals[edgeCount].y(),
662                  normals[edgeCount].z());
663      glVertex3d (vertex[edgeCount].x(),
664                  vertex[edgeCount].y(),
665                  vertex[edgeCount].z());
666    }
667    // Trap situation where number of edges is > 4...
668    if (n > 4) {
669      G4cerr <<
670        "G4OpenGLSceneHandler::AddPrimitive(G4Polyhedron): WARNING";
671      G4PhysicalVolumeModel* pPVModel =
672        dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
673      if (pPVModel) {
674        G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
675        G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
676        G4cerr <<
677        "\n  Volume " << pCurrentPV->GetName() <<
678        ", Solid " << pCurrentLV->GetSolid()->GetName() <<
679          " (" << pCurrentLV->GetSolid()->GetEntityType();
680      }
681      G4cerr<<
682        "\n   G4Polyhedron facet with " << n << " edges" << G4endl;
683    }
684
685    // Do it all over again (twice) for hlr...
686    if  (drawing_style == G4ViewParameters::hlr ||
687         drawing_style == G4ViewParameters::hlhsr) {
688
689      glEnd ();  // Placed here to balance glBegin above, allowing GL
690                 // state changes below, then glBegin again.  Avoids
691                 // having glBegin/End pairs *inside* loop in the more
692                 // usual case of no hidden line removal.
693
[754]694      // Lighting disabled unless otherwise requested
695      glDisable (GL_LIGHTING);
696
[529]697      // Draw through stencil...
698      glStencilFunc (GL_EQUAL, 0, 1);
699      glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
700      if (drawing_style == G4ViewParameters::hlhsr) {
[688]701        if (!fProcessing2D) glEnable (GL_LIGHTING);
[529]702      }
703      glEnable (GL_DEPTH_TEST);
704      glDepthFunc (GL_LEQUAL);   
705      if (materialColour[3] < 1.) {
706        // Transparent...
707        glDepthMask (0);  // Make depth buffer read-only.
708        glDisable (GL_CULL_FACE);
709        glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
710      } else {
711        // Opaque...
712        glDepthMask (1);  // Make depth buffer writable (default).
713        if (clipping) {
714          glDisable (GL_CULL_FACE);
715          glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
716        } else {
717          glEnable (GL_CULL_FACE);
718          glCullFace (GL_BACK);
719          glPolygonMode (GL_FRONT, GL_FILL);
720        }
721      }
722      GLfloat* painting_colour;
723      if  (drawing_style == G4ViewParameters::hlr) {
724        if (materialColour[3] < 1.) {
725          // Transparent - don't paint...
726          goto end_of_drawing_through_stencil;
727        }
728        painting_colour = clear_colour;
729      } else {  // drawing_style == G4ViewParameters::hlhsr
730        painting_colour = materialColour;
731      }
732      if (materialColour[3] < 1.) {
733        // Transparent...
734        glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, painting_colour);
735      } else {
736        // Opaque...
737        glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, painting_colour);
738      }
739      glColor4fv (painting_colour);
740      glBegin (GL_QUADS);
741      for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
742        if (edgeFlag[edgeCount] > 0) {
743          glEdgeFlag (GL_TRUE);
744        } else {
745          glEdgeFlag (GL_FALSE);
746        }
747        glNormal3d (normals[edgeCount].x(),
748                    normals[edgeCount].y(),
749                    normals[edgeCount].z());
750        glVertex3d (vertex[edgeCount].x(),
751                    vertex[edgeCount].y(),
752                    vertex[edgeCount].z());
753      }
754      glEnd ();
755    end_of_drawing_through_stencil:
756
757      // and once more to reset the stencil bits...
758      glStencilFunc (GL_ALWAYS, 0, 1);
759      glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
760      glDepthFunc (GL_LEQUAL);  // to make sure line gets drawn. 
761      if (materialColour[3] < 1.) {
762        // Transparent...
763        glDisable (GL_CULL_FACE);
764        glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
765      } else {
766        // Opaque...
767        if (clipping) {
768          glDisable (GL_CULL_FACE);
769          glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
770        } else {
771          glEnable (GL_CULL_FACE);
772          glCullFace (GL_BACK);
773          glPolygonMode (GL_FRONT, GL_LINE);
774        }
775      }
776      glDisable (GL_LIGHTING);
777      glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
778      glBegin (GL_QUADS);
779      for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
780        if (edgeFlag[edgeCount] > 0) {
781          glEdgeFlag (GL_TRUE);
782        } else {
783          glEdgeFlag (GL_FALSE);
784        }
785        glNormal3d (normals[edgeCount].x(),
786                    normals[edgeCount].y(),
787                    normals[edgeCount].z());
788        glVertex3d (vertex[edgeCount].x(),
789                    vertex[edgeCount].y(),
790                    vertex[edgeCount].z());
791      }
792      glEnd ();
793      glDepthFunc (GL_LEQUAL);   // Revert for next facet.
794      glBegin (GL_QUADS);      // Ready for next facet.  GL
795                               // says it ignores incomplete
796                               // quadrilaterals, so final empty
797                               // glBegin/End sequence should be OK.
798    }
799  } while (notLastFace); 
800 
801  glEnd ();
802  glDisable (GL_STENCIL_TEST);  // Revert to default for next primitive.
803  glDepthMask (1);              // Revert to default for next primitive.
[754]804  glDisable (GL_LIGHTING);      // Revert to default for next primitive.
[529]805}
806
807//Method for handling G4NURBS objects for drawing solids.
808//Knots and Ctrl Pnts MUST be arrays of GLfloats.
809void G4OpenGLSceneHandler::AddPrimitive (const G4NURBS& nurb) {
810
[593]811  // Loads G4Atts for picking...
812  if (fpViewer->GetViewParameters().IsPicking()) {
813    G4AttHolder* holder = new G4AttHolder;
814    LoadAtts(nurb, holder);
815    fPickMap[fPickName] = holder;
816  }
817
[529]818  GLUnurbsObj *gl_nurb;
819  gl_nurb = gluNewNurbsRenderer ();
820
821  GLfloat *u_knot_array, *u_knot_array_ptr;
822  u_knot_array = u_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::U)];
823  G4NURBS::KnotsIterator u_iterator (nurb, G4NURBS::U);
[789]824  while (u_iterator.pick (u_knot_array_ptr++)){}
[529]825
826  GLfloat *v_knot_array, *v_knot_array_ptr;
827  v_knot_array = v_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::V)];
828  G4NURBS::KnotsIterator v_iterator (nurb, G4NURBS::V);
[789]829  while (v_iterator.pick (v_knot_array_ptr++)){}
[529]830
831  GLfloat *ctrl_pnt_array, *ctrl_pnt_array_ptr;
832  ctrl_pnt_array = ctrl_pnt_array_ptr =
833    new GLfloat [nurb.GettotalnbrCtrlPts () * G4NURBS::NofC];
834  G4NURBS::CtrlPtsCoordsIterator c_p_iterator (nurb);
[789]835  while (c_p_iterator.pick (ctrl_pnt_array_ptr++)){}
[529]836
837  // Get vis attributes - pick up defaults if none.
838  const G4VisAttributes* pVA =
839    fpViewer -> GetApplicableVisAttributes (nurb.GetVisAttributes ());
840
841  // Get view parameters that the user can force through the vis
842  // attributes, thereby over-riding the current view parameter.
843  G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
844  //G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
845 
846  //Get colour, etc..
847  const G4Colour& c = pVA -> GetColour ();
848
849  switch (drawing_style) {
850
851  case (G4ViewParameters::hlhsr):
852    //    G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
853    // << "Using hidden surface removal." << G4endl;
854  case (G4ViewParameters::hsr):
855    {
[688]856      if (!fProcessing2D) glEnable (GL_LIGHTING);
[529]857      glEnable (GL_DEPTH_TEST);
858      glEnable (GL_AUTO_NORMAL);
859      glEnable (GL_NORMALIZE);
860      gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_FILL);
861      gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
862      GLfloat materialColour [4];
863      materialColour [0] = c.GetRed ();
864      materialColour [1] = c.GetGreen ();
865      materialColour [2] = c.GetBlue ();
866      materialColour [3] = 1.0;  // = c.GetAlpha () for transparency -
867                                 // but see complication in
868                                 // AddPrimitive(const G4Polyhedron&).
869      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
870      break;
871    }
872  case (G4ViewParameters::hlr):
873    //    G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
874    // << "Using wireframe." << G4endl;
875  case (G4ViewParameters::wireframe):
876  default:
877    glDisable (GL_LIGHTING);
878//    glDisable (GL_DEPTH_TEST);
879    glEnable (GL_DEPTH_TEST);
880    glDisable (GL_AUTO_NORMAL);
881    glDisable (GL_NORMALIZE);
882    gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
883    gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
884    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
885    break;
886  }     
887
888  gluBeginSurface (gl_nurb);
889  G4int u_stride = 4;
890  G4int v_stride = nurb.GetnbrCtrlPts(G4NURBS::U) * 4;
891
892  gluNurbsSurface (gl_nurb,
893                   nurb.GetnbrKnots (G4NURBS::U), (GLfloat*)u_knot_array,
894                   nurb.GetnbrKnots (G4NURBS::V), (GLfloat*)v_knot_array,
895                   u_stride,
896                   v_stride, 
897                   ctrl_pnt_array,
898                   nurb.GetUorder (),
899                   nurb.GetVorder (),
900                   GL_MAP2_VERTEX_4);
901 
902  gluEndSurface (gl_nurb);
903
904  delete [] u_knot_array;  // These should be allocated with smart allocators
905  delete [] v_knot_array;  // to avoid memory explosion.
906  delete [] ctrl_pnt_array;
907
908  gluDeleteNurbsRenderer (gl_nurb);
909}
910
911void G4OpenGLSceneHandler::AddCompound(const G4VTrajectory& traj) {
912  G4VSceneHandler::AddCompound(traj);  // For now.
913}
914
915void G4OpenGLSceneHandler::AddCompound(const G4VHit& hit) {
916  G4VSceneHandler::AddCompound(hit);  // For now.
917}
918
919#endif
Note: See TracBrowser for help on using the repository browser.