source: trunk/geant4/visualization/OpenGL/src/G4OpenGLSceneHandler.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: 25.3 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: G4OpenGLSceneHandler.cc,v 1.45 2006/08/30 11:37:34 allison Exp $
28// GEANT4 tag $Name: geant4-08-02-patch-01 $
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
46#include "G4OpenGLSceneHandler.hh"
47#include "G4OpenGLViewer.hh"
48#include "G4OpenGLFontBaseStore.hh"
49#include "G4OpenGLTransform3D.hh"
50#include "G4Point3D.hh"
51#include "G4Normal3D.hh"
52#include "G4Transform3D.hh"
53#include "G4Polyline.hh"
54#include "G4Text.hh"
55#include "G4Circle.hh"
56#include "G4Square.hh"
57#include "G4VMarker.hh"
58#include "G4Polyhedron.hh"
59#include "G4VisAttributes.hh"
60#include "G4PhysicalVolumeModel.hh"
61#include "G4VPhysicalVolume.hh"
62#include "G4LogicalVolume.hh"
63#include "G4VSolid.hh"
64#include "G4Scene.hh"
65#include "G4VisExtent.hh"
66
67G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4VGraphicsSystem& system,
68                              G4int id,
69                              const G4String& name):
70  G4VSceneHandler (system, id, name)
71{}
72
73G4OpenGLSceneHandler::~G4OpenGLSceneHandler ()
74{
75  ClearStore ();
76}
77
78const GLubyte G4OpenGLSceneHandler::fStippleMaskHashed [128] = {
79  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
80  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
81  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
82  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
83  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
84  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
85  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
86  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
87  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
88  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
89  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
90  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
91  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
92  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
93  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
94  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
95};
96
97const G4Polyhedron* G4OpenGLSceneHandler::CreateSectionPolyhedron ()
98{
99  // Clipping done in G4OpenGLViewer::SetView.
100  return 0;
101
102  // But...OpenGL no longer seems to reconstruct clipped edges, so,
103  // when the BooleanProcessor is up to it, abandon this and use
104  // generic clipping in G4VSceneHandler::CreateSectionPolyhedron...
105  // return G4VSceneHandler::CreateSectionPolyhedron();
106}
107
108const G4Polyhedron* G4OpenGLSceneHandler::CreateCutawayPolyhedron ()
109{
110  // Cutaway done in G4OpenGLViewer::SetView.
111  return 0;
112
113  // But...if not, when the BooleanProcessor is up to it...
114  // return G4VSceneHandler::CreateCutawayPolyhedron();
115}
116
117void G4OpenGLSceneHandler::AddPrimitive (const G4Polyline& line)
118{
119  G4int nPoints = line.size ();
120  if (nPoints <= 0) return;
121
122  // Note: colour treated in sub-class.
123
124  if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ())
125    glDisable (GL_DEPTH_TEST);
126  else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS);}
127
128  glDisable (GL_LIGHTING);
129
130  G4double lineWidth = GetLineWidth(line);
131  glLineWidth(lineWidth);
132
133  glBegin (GL_LINE_STRIP);
134  for (G4int iPoint = 0; iPoint < nPoints; iPoint++) {
135  G4double x, y, z;
136    x = line[iPoint].x();
137    y = line[iPoint].y();
138    z = line[iPoint].z();
139    glVertex3d (x, y, z);
140  }
141  glEnd ();
142}
143
144void G4OpenGLSceneHandler::AddPrimitive (const G4Text& text) {
145
146  const G4Colour& c = GetTextColour (text);  // Picks up default if none.
147  MarkerSizeType sizeType;
148  G4double size = GetMarkerSize (text, sizeType);
149  G4ThreeVector position (text.GetPosition ());
150  G4String textString = text.GetText();
151
152  G4int font_base = G4OpenGLFontBaseStore::GetFontBase(fpViewer,size);
153  if (font_base < 0) {
154    static G4int callCount = 0;
155    ++callCount;
156    if (callCount <= 10 || callCount%100 == 0) {
157      G4cout <<
158        "G4OpenGLSceneHandler::AddPrimitive (const G4Text&) call count "
159             << callCount <<
160        "\n  No fonts available."
161        "\n  Called with text \""
162             << text.GetText ()
163             << "\"\n  at " << position
164             << ", size " << size
165             << ", offsets " << text.GetXOffset () << ", " << text.GetYOffset ()
166             << ", type " << G4int(sizeType)
167             << ", colour " << c
168             << G4endl;
169    }
170    return;
171  }
172  const char* textCString = textString.c_str();
173  glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
174  glDisable (GL_DEPTH_TEST);
175  glDisable (GL_LIGHTING);
176 
177  glRasterPos3f(position.x(),position.y(),position.z());
178  // No action on offset or layout at present.
179  glPushAttrib(GL_LIST_BIT);
180  glListBase(font_base);
181  glCallLists(strlen(textCString), GL_UNSIGNED_BYTE, (GLubyte *)textCString);
182  glPopAttrib();
183}
184
185void G4OpenGLSceneHandler::AddPrimitive (const G4Circle& circle) {
186  glEnable (GL_POINT_SMOOTH);
187  AddCircleSquare (circle, 24);
188}
189
190void G4OpenGLSceneHandler::AddPrimitive (const G4Square& square) {
191  glDisable (GL_POINT_SMOOTH);
192  AddCircleSquare (square, 4);
193}
194
195void G4OpenGLSceneHandler::AddCircleSquare
196(const G4VMarker& marker,
197 G4int nSides) {
198
199  // Note: colour treated in sub-class.
200
201  if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ())
202    glDisable (GL_DEPTH_TEST);
203  else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS);}
204 
205  glDisable (GL_LIGHTING);
206 
207  G4double lineWidth = GetLineWidth(marker);
208  glLineWidth(lineWidth);
209
210  G4VMarker::FillStyle style = marker.GetFillStyle();
211 
212  switch (style) {
213  case G4VMarker::noFill:
214    glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
215    break;
216   
217  case G4VMarker::hashed:
218    /*
219    G4cout << "Hashed fill style in G4OpenGLSceneHandler."
220           << "\n  Not implemented.  Using G4VMarker::filled."
221           << G4endl;
222    */
223    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
224    glPolygonStipple (fStippleMaskHashed);
225    // See also:
226    //   if (style == G4VMarker::filled || style == G4VMarker::hashed)...
227    // (twice) below.
228    break;
229   
230  case G4VMarker::filled:
231    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
232    break;
233   
234  default:
235    G4cout << "Unrecognised fill style in G4OpenGLSceneHandler."
236           << "\n  Using G4VMarker::filled."
237           << G4endl;
238    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
239    break;
240   
241  }
242
243  // A few useful quantities...
244  G4Point3D centre = marker.GetPosition();
245  const G4Vector3D& viewpointDirection =
246    fpViewer -> GetViewParameters().GetViewpointDirection();
247  const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector();
248  MarkerSizeType sizeType;
249  G4double size = GetMarkerSize(marker, sizeType);
250
251  // Find "size" of marker in world space (but see note below)...
252  G4double worldSize;
253  if (sizeType == world) {  // Size specified in world coordinates.
254    worldSize = size;
255  }
256  else { // Size specified in screen (window) coordinates.
257
258    // Find window coordinates of centre...
259    GLdouble modelMatrix[16];
260    glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
261    G4double projectionMatrix[16];
262    glGetDoublev (GL_PROJECTION_MATRIX, projectionMatrix);
263    GLint viewport[4];
264    glGetIntegerv(GL_VIEWPORT,viewport);
265    GLdouble winx, winy, winz;
266    gluProject(centre.x(), centre.y(), centre.z(),
267               modelMatrix, projectionMatrix, viewport,
268               &winx, &winy, &winz);
269
270    // Determine ratio window:world...
271    const G4Vector3D inScreen = (up.cross(viewpointDirection)).unit();
272    const G4Vector3D p = centre + inScreen;
273    GLdouble winDx, winDy, winDz;
274    gluProject(p.x(), p.y(), p.z(),
275               modelMatrix, projectionMatrix, viewport,
276               &winDx, &winDy, &winDz);
277    G4double winWorldRatio = std::sqrt(std::pow(winx - winDx, 2) +
278                                  std::pow(winy - winDy, 2));
279    worldSize = size / winWorldRatio;
280  }
281
282  // Draw...
283  DrawXYPolygon (worldSize, centre, nSides);
284}
285
286/***************************************************
287Note: We have to do it this way round so that when a global
288transformation is applied, such as with /vis/viewer/set/viewpoint,
289the markers follow the world coordinates without having to
290recreate the display lists.  The down side is that the markers
291rotate.  The only way to avoid this is to play with the modelview
292and projection matrices of OpenGL - which I need to think about.
293For future reference, here is the code to draw in window
294coordinates; its down side is that markers do not follow global
295transformations.  Some clever stuff is needed.
296
297  ...
298  // Find window coordinates of centre...
299  GLdouble modelMatrix[16];
300  glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
301  G4double projectionMatrix[16];
302  glGetDoublev (GL_PROJECTION_MATRIX, projectionMatrix);
303  GLint viewport[4];
304  glGetIntegerv(GL_VIEWPORT,viewport);
305  GLdouble winx, winy, winz;
306  gluProject(centre.x(), centre.y(), centre.z(),
307             modelMatrix, projectionMatrix, viewport,
308             &winx, &winy, &winz);
309
310  // Find window size...
311  G4double winSize;
312  if (size) {  // Size specified in world coordinates.
313    // Determine size in window coordinates...
314    (Note: improve this by using an inScreen vector as above.)
315    GLdouble winx1, winy1, winz1;
316    gluProject(centre.x() + size, centre.y() + size, centre.z() + size,
317               modelMatrix, projectionMatrix, viewport,
318               &winx1, &winy1, &winz1);
319    winSize = std::sqrt((std::pow(winx - winx1, 2) +
320                    std::pow(winy - winy1, 2) +
321                    std::pow(winz - winz1, 2)) / 3.);
322  }
323  else {
324    winSize = scale *
325      userSpecified ? marker.GetScreenSize() : def.GetScreenSize();
326  }
327
328  // Prepare to draw in window coordinates...
329  glMatrixMode (GL_PROJECTION);
330  glPushMatrix();
331  glLoadIdentity();
332  gluOrtho2D(GLdouble(viewport[0]),
333             GLdouble(viewport[0] + viewport[2]),
334             GLdouble(viewport[1]),
335             GLdouble(viewport[1] + viewport[3]));
336  glMatrixMode (GL_MODELVIEW);
337  glPushMatrix();
338  glLoadIdentity();
339
340  // Draw in window coordinates...
341  DrawScreenPolygon (winSize, G4Point3D(winx, winy, winz), nSides);
342
343  // Re-instate matrices...
344  glMatrixMode (GL_PROJECTION);
345  glPopMatrix();
346  glMatrixMode (GL_MODELVIEW);
347  glPopMatrix();
348  ...
349}
350
351void G4OpenGLSceneHandler::DrawScreenPolygon
352(G4double size,
353 const G4Point3D& centre,
354 G4int nSides) {
355  glBegin (GL_POLYGON);
356  const G4double dPhi = twopi / nSides;
357  const G4double r = size / 2.;
358  G4double phi;
359  G4int i;
360  for (i = 0, phi = -dPhi / 2.; i < nSides; i++, phi += dPhi) {
361    G4double x, y, z;
362    x = centre.x() + r * std::cos(phi);
363    y = centre.y() + r * std::sin(phi);
364    z = centre.z();
365    glVertex3d (x, y, z);
366  }
367  glEnd ();
368}
369**********************************************/
370
371void G4OpenGLSceneHandler::DrawXYPolygon
372(G4double size,
373 const G4Point3D& centre,
374 G4int nSides) {
375  const G4Vector3D& viewpointDirection =
376    fpViewer -> GetViewParameters().GetViewpointDirection();
377  const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector();
378  const G4double dPhi = twopi / nSides;
379  const G4double radius = size / 2.;
380  G4Vector3D start = radius * (up.cross(viewpointDirection)).unit();
381  G4double phi;
382  G4int i;
383  glBegin (GL_POLYGON);
384  for (i = 0, phi = 0.; i < nSides; i++, phi += dPhi) {
385    G4Vector3D r = start; r.rotate(phi, viewpointDirection);
386    G4Vector3D p = centre + r;
387    glVertex3d (p.x(), p.y(), p.z());
388  }
389  glEnd ();
390}
391
392//Method for handling G4Polyhedron objects for drawing solids.
393void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
394
395  // Assume all facets are planar convex quadrilaterals.
396  // Draw each facet individually
397 
398  if (polyhedron.GetNoFacets() == 0) return;
399
400  // Get vis attributes - pick up defaults if none.
401  const G4VisAttributes* pVA =
402    fpViewer -> GetApplicableVisAttributes (polyhedron.GetVisAttributes ());
403
404  // Get view parameters that the user can force through the vis
405  // attributes, thereby over-riding the current view parameter.
406  G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
407
408  //Get colour, etc...
409  G4bool transparency_enabled = true;
410  G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
411  if (pViewer) transparency_enabled = pViewer->transparency_enabled;
412  const G4Colour& c = GetColour (polyhedron);
413  GLfloat materialColour [4];
414  materialColour [0] = c.GetRed ();
415  materialColour [1] = c.GetGreen ();
416  materialColour [2] = c.GetBlue ();
417  if (transparency_enabled) {
418    materialColour [3] = c.GetAlpha ();
419  } else {
420    materialColour [3] = 1.;
421  }
422
423  G4double lineWidth = GetLineWidth(polyhedron);
424  glLineWidth(lineWidth);
425
426  GLfloat clear_colour[4];
427  glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour);
428
429  G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
430
431  G4bool clipping = pViewer->fVP.IsSection() || pViewer->fVP.IsCutaway();
432
433  switch (drawing_style) {
434  case (G4ViewParameters::hlhsr):
435    // Set up as for hidden line removal but paint polygon faces later...
436  case (G4ViewParameters::hlr):
437    glEnable (GL_STENCIL_TEST);
438    // The stencil buffer is cleared in G4OpenGLViewer::ClearView.
439    // The procedure below leaves it clear.
440    glStencilFunc (GL_ALWAYS, 0, 1);
441    glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
442    glEnable (GL_DEPTH_TEST);
443    glDepthFunc (GL_LEQUAL);
444    if (materialColour[3] < 1.) {
445      // Transparent...
446      glDisable (GL_CULL_FACE);
447      glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
448    } else {
449      // Opaque...
450      if (clipping) {
451        glDisable (GL_CULL_FACE);
452        glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
453      } else {
454        glEnable (GL_CULL_FACE);
455        glCullFace (GL_BACK);
456        glPolygonMode (GL_FRONT, GL_LINE);
457      }
458    }
459    glDisable (GL_LIGHTING);
460    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
461    break;
462  case (G4ViewParameters::hsr):
463    glEnable (GL_DEPTH_TEST);
464    glDepthFunc (GL_LEQUAL);   
465    if (materialColour[3] < 1.) {
466      // Transparent...
467      glDepthMask (0);  // Make depth buffer read-only.
468      glDisable (GL_CULL_FACE);
469      glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
470      glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, materialColour);
471    } else {
472      // Opaque...
473      glDepthMask (1);  // Make depth buffer writable (default).
474      if (clipping) {
475        glDisable (GL_CULL_FACE);
476        glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
477      } else {
478        glEnable (GL_CULL_FACE);
479        glCullFace (GL_BACK);
480        glPolygonMode (GL_FRONT, GL_FILL);
481      }
482      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
483    }
484    glEnable (GL_LIGHTING);
485    break;
486  case (G4ViewParameters::wireframe):
487  default:
488    glEnable (GL_DEPTH_TEST);
489    glDepthFunc (GL_LEQUAL);    //??? was GL_ALWAYS
490    glDisable (GL_CULL_FACE);
491    glDisable (GL_LIGHTING);
492    glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
493    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
494    break;
495  }
496
497  //Loop through all the facets...
498  glBegin (GL_QUADS);
499  G4bool notLastFace;
500  do {
501
502    //First, find vertices, edgeflags and normals and note "not last facet"...
503    G4Point3D vertex[4];
504    G4int edgeFlag[4];
505    G4Normal3D normals[4];
506    G4int n;
507    notLastFace = polyhedron.GetNextFacet(n, vertex, edgeFlag, normals);
508
509    //Loop through the four edges of each G4Facet...
510    G4int edgeCount = 0;
511    for(edgeCount = 0; edgeCount < n; ++edgeCount) {
512      // Check to see if edge is visible or not...
513      if (isAuxEdgeVisible) {
514        edgeFlag[edgeCount] = 1;
515      }
516      if (edgeFlag[edgeCount] > 0) {
517        glEdgeFlag (GL_TRUE);
518      } else {
519        glEdgeFlag (GL_FALSE);
520      }
521      glNormal3d (normals[edgeCount].x(),
522                  normals[edgeCount].y(),
523                  normals[edgeCount].z());
524      glVertex3d (vertex[edgeCount].x(),
525                  vertex[edgeCount].y(),
526                  vertex[edgeCount].z());
527    }
528    // HepPolyhedron produces triangles too; in that case add an extra
529    // vertex identical to first...
530    if (n == 3) {
531      edgeCount = 3;
532      normals[edgeCount] = normals[0];
533      vertex[edgeCount] = vertex[0];
534      edgeFlag[edgeCount] = -1;
535      glEdgeFlag (GL_FALSE);
536      glNormal3d (normals[edgeCount].x(),
537                  normals[edgeCount].y(),
538                  normals[edgeCount].z());
539      glVertex3d (vertex[edgeCount].x(),
540                  vertex[edgeCount].y(),
541                  vertex[edgeCount].z());
542    }
543    // Trap situation where number of edges is > 4...
544    if (n > 4) {
545      G4cerr <<
546        "G4OpenGLSceneHandler::AddPrimitive(G4Polyhedron): WARNING";
547      G4PhysicalVolumeModel* pPVModel =
548        dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
549      if (pPVModel) {
550        G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
551        G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
552        G4cerr <<
553        "\n  Volume " << pCurrentPV->GetName() <<
554        ", Solid " << pCurrentLV->GetSolid()->GetName() <<
555          " (" << pCurrentLV->GetSolid()->GetEntityType();
556      }
557      G4cerr<<
558        "\n   G4Polyhedron facet with " << n << " edges" << G4endl;
559    }
560
561    // Do it all over again (twice) for hlr...
562    if  (drawing_style == G4ViewParameters::hlr ||
563         drawing_style == G4ViewParameters::hlhsr) {
564
565      glEnd ();  // Placed here to balance glBegin above, allowing GL
566                 // state changes below, then glBegin again.  Avoids
567                 // having glBegin/End pairs *inside* loop in the more
568                 // usual case of no hidden line removal.
569
570      // Draw through stencil...
571      glStencilFunc (GL_EQUAL, 0, 1);
572      glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
573      if (drawing_style == G4ViewParameters::hlhsr) {
574        glEnable (GL_LIGHTING);
575      }
576      glEnable (GL_DEPTH_TEST);
577      glDepthFunc (GL_LEQUAL);   
578      if (materialColour[3] < 1.) {
579        // Transparent...
580        glDepthMask (0);  // Make depth buffer read-only.
581        glDisable (GL_CULL_FACE);
582        glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
583      } else {
584        // Opaque...
585        glDepthMask (1);  // Make depth buffer writable (default).
586        if (clipping) {
587          glDisable (GL_CULL_FACE);
588          glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
589        } else {
590          glEnable (GL_CULL_FACE);
591          glCullFace (GL_BACK);
592          glPolygonMode (GL_FRONT, GL_FILL);
593        }
594      }
595      GLfloat* painting_colour;
596      if  (drawing_style == G4ViewParameters::hlr) {
597        if (materialColour[3] < 1.) {
598          // Transparent - don't paint...
599          goto end_of_drawing_through_stencil;
600        }
601        painting_colour = clear_colour;
602      } else {  // drawing_style == G4ViewParameters::hlhsr
603        painting_colour = materialColour;
604      }
605      if (materialColour[3] < 1.) {
606        // Transparent...
607        glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, painting_colour);
608      } else {
609        // Opaque...
610        glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, painting_colour);
611      }
612      glColor4fv (painting_colour);
613      glBegin (GL_QUADS);
614      for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
615        if (edgeFlag[edgeCount] > 0) {
616          glEdgeFlag (GL_TRUE);
617        } else {
618          glEdgeFlag (GL_FALSE);
619        }
620        glNormal3d (normals[edgeCount].x(),
621                    normals[edgeCount].y(),
622                    normals[edgeCount].z());
623        glVertex3d (vertex[edgeCount].x(),
624                    vertex[edgeCount].y(),
625                    vertex[edgeCount].z());
626      }
627      glEnd ();
628    end_of_drawing_through_stencil:
629
630      // and once more to reset the stencil bits...
631      glStencilFunc (GL_ALWAYS, 0, 1);
632      glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
633      glDepthFunc (GL_LEQUAL);  // to make sure line gets drawn. 
634      if (materialColour[3] < 1.) {
635        // Transparent...
636        glDisable (GL_CULL_FACE);
637        glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
638      } else {
639        // Opaque...
640        if (clipping) {
641          glDisable (GL_CULL_FACE);
642          glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
643        } else {
644          glEnable (GL_CULL_FACE);
645          glCullFace (GL_BACK);
646          glPolygonMode (GL_FRONT, GL_LINE);
647        }
648      }
649      glDisable (GL_LIGHTING);
650      glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
651      glBegin (GL_QUADS);
652      for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
653        if (edgeFlag[edgeCount] > 0) {
654          glEdgeFlag (GL_TRUE);
655        } else {
656          glEdgeFlag (GL_FALSE);
657        }
658        glNormal3d (normals[edgeCount].x(),
659                    normals[edgeCount].y(),
660                    normals[edgeCount].z());
661        glVertex3d (vertex[edgeCount].x(),
662                    vertex[edgeCount].y(),
663                    vertex[edgeCount].z());
664      }
665      glEnd ();
666      glDepthFunc (GL_LEQUAL);   // Revert for next facet.
667      glBegin (GL_QUADS);      // Ready for next facet.  GL
668                               // says it ignores incomplete
669                               // quadrilaterals, so final empty
670                               // glBegin/End sequence should be OK.
671    }
672  } while (notLastFace); 
673 
674  glEnd ();
675  glDisable (GL_STENCIL_TEST);  // Revert to default for next primitive.
676  glDepthMask (1);              // Revert to default for next primitive.
677}
678
679//Method for handling G4NURBS objects for drawing solids.
680//Knots and Ctrl Pnts MUST be arrays of GLfloats.
681void G4OpenGLSceneHandler::AddPrimitive (const G4NURBS& nurb) {
682
683  GLUnurbsObj *gl_nurb;
684  gl_nurb = gluNewNurbsRenderer ();
685
686  GLfloat *u_knot_array, *u_knot_array_ptr;
687  u_knot_array = u_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::U)];
688  G4NURBS::KnotsIterator u_iterator (nurb, G4NURBS::U);
689  while (u_iterator.pick (u_knot_array_ptr++));
690
691  GLfloat *v_knot_array, *v_knot_array_ptr;
692  v_knot_array = v_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::V)];
693  G4NURBS::KnotsIterator v_iterator (nurb, G4NURBS::V);
694  while (v_iterator.pick (v_knot_array_ptr++));
695
696  GLfloat *ctrl_pnt_array, *ctrl_pnt_array_ptr;
697  ctrl_pnt_array = ctrl_pnt_array_ptr =
698    new GLfloat [nurb.GettotalnbrCtrlPts () * G4NURBS::NofC];
699  G4NURBS::CtrlPtsCoordsIterator c_p_iterator (nurb);
700  while (c_p_iterator.pick (ctrl_pnt_array_ptr++));
701
702  // Get vis attributes - pick up defaults if none.
703  const G4VisAttributes* pVA =
704    fpViewer -> GetApplicableVisAttributes (nurb.GetVisAttributes ());
705
706  // Get view parameters that the user can force through the vis
707  // attributes, thereby over-riding the current view parameter.
708  G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
709  //G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
710 
711  //Get colour, etc..
712  const G4Colour& c = pVA -> GetColour ();
713
714  switch (drawing_style) {
715
716  case (G4ViewParameters::hlhsr):
717    //    G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
718    // << "Using hidden surface removal." << G4endl;
719  case (G4ViewParameters::hsr):
720    {
721      glEnable (GL_LIGHTING);
722      glEnable (GL_DEPTH_TEST);
723      glEnable (GL_AUTO_NORMAL);
724      glEnable (GL_NORMALIZE);
725      gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_FILL);
726      gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
727      GLfloat materialColour [4];
728      materialColour [0] = c.GetRed ();
729      materialColour [1] = c.GetGreen ();
730      materialColour [2] = c.GetBlue ();
731      materialColour [3] = 1.0;  // = c.GetAlpha () for transparency -
732                                 // but see complication in
733                                 // AddPrimitive(const G4Polyhedron&).
734      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
735      break;
736    }
737  case (G4ViewParameters::hlr):
738    //    G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
739    // << "Using wireframe." << G4endl;
740  case (G4ViewParameters::wireframe):
741  default:
742    glDisable (GL_LIGHTING);
743//    glDisable (GL_DEPTH_TEST);
744    glEnable (GL_DEPTH_TEST);
745    glDisable (GL_AUTO_NORMAL);
746    glDisable (GL_NORMALIZE);
747    gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
748    gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
749    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
750    break;
751  }     
752
753  gluBeginSurface (gl_nurb);
754  G4int u_stride = 4;
755  G4int v_stride = nurb.GetnbrCtrlPts(G4NURBS::U) * 4;
756
757  gluNurbsSurface (gl_nurb,
758                   nurb.GetnbrKnots (G4NURBS::U), (GLfloat*)u_knot_array,
759                   nurb.GetnbrKnots (G4NURBS::V), (GLfloat*)v_knot_array,
760                   u_stride,
761                   v_stride, 
762                   ctrl_pnt_array,
763                   nurb.GetUorder (),
764                   nurb.GetVorder (),
765                   GL_MAP2_VERTEX_4);
766 
767  gluEndSurface (gl_nurb);
768
769  delete [] u_knot_array;  // These should be allocated with smart allocators
770  delete [] v_knot_array;  // to avoid memory explosion.
771  delete [] ctrl_pnt_array;
772
773  gluDeleteNurbsRenderer (gl_nurb);
774}
775
776void G4OpenGLSceneHandler::AddCompound(const G4VTrajectory& traj) {
777  G4VSceneHandler::AddCompound(traj);  // For now.
778}
779
780void G4OpenGLSceneHandler::AddCompound(const G4VHit& hit) {
781  G4VSceneHandler::AddCompound(hit);  // For now.
782}
783
784#endif
Note: See TracBrowser for help on using the repository browser.