Geant4  10.01.p03
G4OpenGLSceneHandler.cc
Go to the documentation of this file.
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 85263 2014-10-27 08:58:31Z gcosmo $
28 //
29 //
30 // Andrew Walkden 27th March 1996
31 // OpenGL stored scene - creates OpenGL display lists.
32 // OpenGL immediate scene - draws immediately to buffer
33 // (saving space on server).
34 
35 #ifdef G4VIS_BUILD_OPENGL_DRIVER
36 
37 #include "G4OpenGLSceneHandler.hh"
38 #include "G4OpenGLViewer.hh"
39 #include "G4OpenGLTransform3D.hh"
40 #include "G4Point3D.hh"
41 #include "G4Normal3D.hh"
42 #include "G4Transform3D.hh"
43 #include "G4Polyline.hh"
44 #include "G4Polymarker.hh"
45 #include "G4Text.hh"
46 #include "G4Circle.hh"
47 #include "G4Square.hh"
48 #include "G4VMarker.hh"
49 #include "G4Polyhedron.hh"
50 #include "G4VisAttributes.hh"
51 #include "G4PhysicalVolumeModel.hh"
52 #include "G4VPhysicalVolume.hh"
53 #include "G4LogicalVolume.hh"
54 #include "G4VSolid.hh"
55 #include "G4Scene.hh"
56 #include "G4VisExtent.hh"
57 #include "G4AttHolder.hh"
58 #include "G4PhysicalConstants.hh"
59 
60 G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4VGraphicsSystem& system,
61  G4int id,
62  const G4String& name):
63 G4VSceneHandler (system, id, name),
64 #ifdef G4OPENGL_VERSION_2
65 fEmulate_GL_QUADS(false),
66 #endif
67 fPickName(0),
68 // glFlush take about 90% time. Dividing glFlush number by 100 will
69 // change the first vis time from 100% to 10+90/100 = 10,9%.
70 fEventsDrawInterval(1),
71 fEventsWaitingToBeFlushed(0),
72 fThreePassCapable(false),
73 fSecondPassForTransparencyRequested(false),
74 fSecondPassForTransparency(false),
75 fThirdPassForNonHiddenMarkersRequested(false),
76 fThirdPassForNonHiddenMarkers(false),
77 fEdgeFlag(true)
78 {
79 }
80 
81 G4OpenGLSceneHandler::~G4OpenGLSceneHandler ()
82 {
83  ClearStore ();
84 }
85 
86 const GLubyte G4OpenGLSceneHandler::fStippleMaskHashed [128] = {
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  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
96  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
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 };
104 
105 void G4OpenGLSceneHandler::ClearAndDestroyAtts()
106 {
107  std::map<GLuint, G4AttHolder*>::iterator i;
108  for (i = fPickMap.begin(); i != fPickMap.end(); ++i) delete i->second;
109  fPickMap.clear();
110 }
111 
112 void G4OpenGLSceneHandler::ScaledFlush()
113 {
114  fEventsWaitingToBeFlushed++;
115  if (fEventsWaitingToBeFlushed < fEventsDrawInterval) return;
116  glFlush();
117  fEventsWaitingToBeFlushed = 0;
118 }
119 
120 void G4OpenGLSceneHandler::ProcessScene()
121 {
122  fThreePassCapable = true;
123 
125 
126  // Repeat if required...
127  if (fSecondPassForTransparencyRequested) {
128  fSecondPassForTransparency = true;
130  fSecondPassForTransparency = false;
131  fSecondPassForTransparencyRequested = false;
132  }
133 
134  // And again if required...
135  if (fThirdPassForNonHiddenMarkersRequested) {
136  fThirdPassForNonHiddenMarkers = true;
138  fThirdPassForNonHiddenMarkers = false;
139  fThirdPassForNonHiddenMarkersRequested = false;
140  }
141 
142  fThreePassCapable = false;
143 }
144 
145 void G4OpenGLSceneHandler::PreAddSolid
146 (const G4Transform3D& objectTransformation,
147  const G4VisAttributes& visAttribs)
148 {
149  G4VSceneHandler::PreAddSolid (objectTransformation, visAttribs);
150 }
151 
152 void G4OpenGLSceneHandler::BeginPrimitives
153 (const G4Transform3D& objectTransformation)
154 {
155  G4VSceneHandler::BeginPrimitives (objectTransformation);
156 }
157 
158 void G4OpenGLSceneHandler::EndPrimitives ()
159 {
161 }
162 
163 void G4OpenGLSceneHandler::BeginPrimitives2D
164 (const G4Transform3D& objectTransformation)
165 {
166  G4VSceneHandler::BeginPrimitives2D (objectTransformation);
167 }
168 
169 void G4OpenGLSceneHandler::EndPrimitives2D ()
170 {
172 }
173 
174 G4VSolid* G4OpenGLSceneHandler::CreateSectionSolid ()
175 {
176  // Clipping done in G4OpenGLViewer::SetView.
177  // return 0;
178 
179  // But...OpenGL no longer seems to reconstruct clipped edges, so,
180  // when the BooleanProcessor is up to it, abandon this and use
181  // generic clipping in G4VSceneHandler::CreateSectionSolid...
183 }
184 
185 G4VSolid* G4OpenGLSceneHandler::CreateCutawaySolid ()
186 {
187  // Cutaway done in G4OpenGLViewer::SetView.
188  // return 0;
189 
190  // But...if not, when the BooleanProcessor is up to it...
192 }
193 
194 void G4OpenGLSceneHandler::AddPrimitive (const G4Polyline& line)
195 {
196  G4int nPoints = line.size ();
197  if (nPoints <= 0) return;
198 
199  // Note: colour and depth test treated in sub-class.
200 
201 #ifndef G4OPENGL_VERSION_2
202  glDisable (GL_LIGHTING);
203 #endif
204 
205  // Get vis attributes - pick up defaults if none.
206  const G4VisAttributes* pVA =
207  fpViewer -> GetApplicableVisAttributes (line.GetVisAttributes ());
208 
209  G4double lineWidth = GetLineWidth(pVA);
210  // Need access to method in G4OpenGLViewer. static_cast doesn't
211  // work with a virtual base class, so use dynamic_cast. No need to
212  // test the outcome since viewer is guaranteed to be a
213  // G4OpenGLViewer, but test it anyway to keep Coverity happy.
214  G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
215  if (pGLViewer) pGLViewer->ChangeLineWidth(lineWidth);
216 
217  fEdgeFlag = true;
218 #ifndef G4OPENGL_VERSION_2
219  glBegin (GL_LINE_STRIP);
220  // No ned glEdgeFlag for lines :
221  // Boundary and nonboundary edge flags on vertices are significant only if GL_POLYGON_MODE is set to GL_POINT or GL_LINE. See glPolygonMode.
222 
223  // glEdgeFlag (GL_TRUE);
224  for (G4int iPoint = 0; iPoint < nPoints; iPoint++) {
225  G4double x, y, z;
226  x = line[iPoint].x();
227  y = line[iPoint].y();
228  z = line[iPoint].z();
229  glVertex3d (x, y, z);
230  }
231  glEnd ();
232 #else
233  glBeginVBO(GL_LINE_STRIP);
234 
235  for (G4int iPoint = 0; iPoint < nPoints; iPoint++) {
236  fOglVertex.push_back(line[iPoint].x());
237  fOglVertex.push_back(line[iPoint].y());
238  fOglVertex.push_back(line[iPoint].z());
239  // normal
240  fOglVertex.push_back(0);
241  fOglVertex.push_back(0);
242  fOglVertex.push_back(1);
243  }
244 
245  glEndVBO();
246 #endif
247 }
248 
249 void G4OpenGLSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
250 {
251  if (polymarker.size() == 0) {
252  return;
253  }
254 
255  // Note: colour and depth test treated in sub-class.
256 
257 #ifndef G4OPENGL_VERSION_2
258  glDisable (GL_LIGHTING);
259 #endif
260 
261  // Get vis attributes - pick up defaults if none.
262  const G4VisAttributes* pVA =
263  fpViewer -> GetApplicableVisAttributes (polymarker.GetVisAttributes ());
264 
265  MarkerSizeType sizeType;
266  G4double size = GetMarkerSize(polymarker, sizeType);
267 
268  // Need access to method in G4OpenGLViewer. static_cast doesn't
269  // work with a virtual base class, so use dynamic_cast. No need to
270  // test the outcome since viewer is guaranteed to be a
271  // G4OpenGLViewer, but test it anyway to keep Coverity happy.
272  G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
273  if (!pGLViewer) return;
274 
275  if (sizeType == world) { // Size specified in world coordinates.
276  G4double lineWidth = GetLineWidth(pVA);
277  pGLViewer->ChangeLineWidth(lineWidth);
278 
279  G4VMarker::FillStyle style = polymarker.GetFillStyle();
280 
281  // G4bool filled = false; Not actually used - comment out to prevent compiler warnings (JA).
282  static G4bool hashedWarned = false;
283 
284  switch (style) {
285  case G4VMarker::noFill:
286  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
287  glEdgeFlag (GL_TRUE);
288  //filled = false;
289  break;
290  case G4VMarker::hashed:
291  if (!hashedWarned) {
292  G4cout << "Hashed fill style in G4OpenGLSceneHandler."
293  << "\n Not implemented. Using G4VMarker::filled."
294  << G4endl;
295  hashedWarned = true;
296  }
297  // Maybe use
298  //glPolygonStipple (fStippleMaskHashed);
299  // Drop through to filled...
300  case G4VMarker::filled:
301  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
302  //filled = true;
303  break;
304  }
305  }
306 
307  // Draw...
308  if (sizeType == world) { // Size specified in world coordinates.
309 
310  G4int nSides;
311  G4double startPhi;
312  switch (polymarker.GetMarkerType()) {
313  default:
314  case G4Polymarker::dots:
315  size = 1.;
316  // Drop through to circles
318  nSides = GetNoOfSides(pVA);
319  startPhi = 0.;
320  break;
322  nSides = 4;
323  startPhi = -pi / 4.;
324  break;
325  }
326 
327  const G4Vector3D& viewpointDirection =
328  fpViewer -> GetViewParameters().GetViewpointDirection();
329  const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector();
330  const G4double dPhi = twopi / nSides;
331  const G4double radius = size / 2.;
332  G4Vector3D start = radius * (up.cross(viewpointDirection)).unit();
333  G4double phi;
334  G4int i;
335  for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
336  fEdgeFlag = true;
337 #ifndef G4OPENGL_VERSION_2
338  glBegin (GL_POLYGON);
339  for (i = 0, phi = startPhi; i < nSides; i++, phi += dPhi) {
340  G4Vector3D r = start; r.rotate(phi, viewpointDirection);
341  G4Vector3D p = polymarker[iPoint] + r;
342  glVertex3d (p.x(), p.y(), p.z());
343  }
344  glEnd ();
345 #else
346  glBeginVBO (GL_TRIANGLE_STRIP);
347  for (i = 0, phi = startPhi; i < nSides; i++, phi += dPhi) {
348  G4Vector3D r = start; r.rotate(phi, viewpointDirection);
349  G4Vector3D p = polymarker[iPoint] + r;
350 
351 #ifdef G4DEBUG_VIS_OGL
352  printf(".....G4OpenGLSceneHandler::AddPrimitive polyhedron QUADS VBO 5\n");
353 #endif
354  fOglVertex.push_back(p.x());
355  fOglVertex.push_back(p.y());
356  fOglVertex.push_back(p.z());
357  // normal
358  fOglVertex.push_back(0);
359  fOglVertex.push_back(0);
360  fOglVertex.push_back(1);
361  }
362  glEndVBO ();
363 #endif
364  }
365 
366  } else { // Size specified in screen (window) coordinates.
367 
368  pGLViewer->ChangePointSize(size);
369 
370  //Antialiasing only for circles
371 #ifndef G4OPENGL_VERSION_2
372  switch (polymarker.GetMarkerType()) {
373  default:
374  case G4Polymarker::dots:
376  glEnable (GL_POINT_SMOOTH); break;
378  glDisable (GL_POINT_SMOOTH); break;
379  }
380 #endif
381 #ifndef G4OPENGL_VERSION_2
382  glBegin (GL_POINTS);
383  for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
384  G4Point3D centre = polymarker[iPoint];
385  glVertex3d(centre.x(),centre.y(),centre.z());
386  }
387  glEnd();
388 #else
389  glBeginVBO(GL_POINTS);
390 
391  for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
392  fOglVertex.push_back(polymarker[iPoint].x());
393  fOglVertex.push_back(polymarker[iPoint].y());
394  fOglVertex.push_back(polymarker[iPoint].z());
395  fOglVertex.push_back(0);
396  fOglVertex.push_back(0);
397  fOglVertex.push_back(1);
398  }
399  glEndVBO();
400 #endif
401  }
402 }
403 
404 void G4OpenGLSceneHandler::AddPrimitive (const G4Text& text) {
405  // Pass to specific viewer via virtual function DrawText.
406  // FIXME : Not ready for OPENGL2 for the moment
407 #ifdef G4OPENGL_VERSION_2
408  return;
409 #endif
410  G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
411  if (pGLViewer) pGLViewer->DrawText(text);
412 }
413 
414 void G4OpenGLSceneHandler::AddPrimitive (const G4Circle& circle) {
415  G4Polymarker oneCircle(circle);
416  oneCircle.push_back(circle.GetPosition());
417  oneCircle.SetMarkerType(G4Polymarker::circles);
418  // Call this AddPrimitive to avoid re-doing sub-class code.
419  G4OpenGLSceneHandler::AddPrimitive(oneCircle);
420 }
421 
422 void G4OpenGLSceneHandler::AddPrimitive (const G4Square& square) {
423  G4Polymarker oneSquare(square);
424  oneSquare.push_back(square.GetPosition());
425  oneSquare.SetMarkerType(G4Polymarker::squares);
426  // Call this AddPrimitive to avoid re-doing sub-class code.
427  G4OpenGLSceneHandler::AddPrimitive(oneSquare);
428 }
429 
430 void G4OpenGLSceneHandler::AddPrimitive (const G4Scale& scale)
431 {
433 }
434 
435 //Method for handling G4Polyhedron objects for drawing solids.
436 void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
437 
438  // Assume all facets are planar convex quadrilaterals.
439  // Draw each facet individually
440 
441  if (polyhedron.GetNoFacets() == 0) return;
442 
443  // Need access to data in G4OpenGLViewer. static_cast doesn't work
444  // with a virtual base class, so use dynamic_cast.
445  G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
446  if (!pGLViewer) return;
447 
448  // Get vis attributes - pick up defaults if none.
449  const G4VisAttributes* pVA =
450  fpViewer -> GetApplicableVisAttributes (polyhedron.GetVisAttributes ());
451 
452  // Get view parameters that the user can force through the vis
453  // attributes, thereby over-riding the current view parameter.
454  G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
455 
456  // Note that in stored mode, because this call gets embedded in a display
457  // list, it is the colour _at the time of_ creation of the display list, so
458  // even if the colour is changed, for example, by interaction with a Qt
459  // window, current_colour does not change.
460  GLfloat* painting_colour;
461  GLfloat current_colour [4];
462  glGetFloatv (GL_CURRENT_COLOR, current_colour);
463 
464  G4bool isTransparent = false;
465  if (current_colour[3] < 1.) { // This object is transparent
466  isTransparent = true;
467  }
468 
469 
470  if (drawing_style == G4ViewParameters::hlr) {
471  // This is the colour used to paint surfaces in hlr mode.
472  GLfloat clear_colour[4];
473  glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour);
474  painting_colour = clear_colour;
475  } else { // drawing_style == G4ViewParameters::hlhsr
476  painting_colour = current_colour;
477  }
478 
479  G4double lineWidth = GetLineWidth(pVA);
480  pGLViewer->ChangeLineWidth(lineWidth);
481 
482  G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
483 
484  G4bool clipping = pGLViewer->fVP.IsSection() || pGLViewer->fVP.IsCutaway();
485 
486  // Lighting disabled unless otherwise requested
487 #ifndef G4OPENGL_VERSION_2
488  glDisable (GL_LIGHTING);
489 #endif
490 
491  switch (drawing_style) {
493  // Set up as for hidden line removal but paint polygon faces later...
494  case (G4ViewParameters::hlr):
495  glEnable (GL_STENCIL_TEST);
496  // The stencil buffer is cleared in G4OpenGLViewer::ClearView.
497  // The procedure below leaves it clear.
498  glStencilFunc (GL_ALWAYS, 0, 1);
499  glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
500  glEnable (GL_DEPTH_TEST);
501  glDepthFunc (GL_LEQUAL);
502  if (isTransparent) {
503  // Transparent...
504  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
505  glEnable(GL_COLOR_MATERIAL);
506  glDisable (GL_CULL_FACE);
507  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
508  } else {
509  // Opaque...
510  if (clipping) {
511  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
512  glEnable(GL_COLOR_MATERIAL);
513  glDisable (GL_CULL_FACE);
514  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
515  } else {
516  glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
517  glEnable(GL_COLOR_MATERIAL);
518  glEnable (GL_CULL_FACE);
519  glCullFace (GL_BACK);
520  glPolygonMode (GL_FRONT, GL_LINE);
521  }
522  }
523  break;
524  case (G4ViewParameters::hsr):
525  glEnable (GL_DEPTH_TEST);
526  glDepthFunc (GL_LEQUAL);
527  if (isTransparent) {
528  // Transparent...
529  glDepthMask (GL_FALSE); // Make depth buffer read-only.
530  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
531 #ifndef G4OPENGL_VERSION_2
532  glEnable(GL_COLOR_MATERIAL);
533 #endif
534  glDisable (GL_CULL_FACE);
535  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
536  } else {
537  // Opaque...
538  glDepthMask (GL_TRUE); // Make depth buffer writable (default).
539  if (clipping) {
540  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
541  glEnable(GL_COLOR_MATERIAL);
542  glDisable (GL_CULL_FACE);
543  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
544  } else {
545  glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
546 #ifndef G4OPENGL_VERSION_2
547  glEnable(GL_COLOR_MATERIAL);
548 #endif
549  glEnable (GL_CULL_FACE);
550  glCullFace (GL_BACK);
551  glPolygonMode (GL_FRONT, GL_FILL);
552  }
553  }
554 #ifndef G4OPENGL_VERSION_2
555  if (!fProcessing2D) glEnable (GL_LIGHTING);
556 #endif
557  break;
559  default:
560  glEnable (GL_DEPTH_TEST);
561  glDepthFunc (GL_LEQUAL); //??? was GL_ALWAYS
562  glDisable (GL_CULL_FACE);
563  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
564  break;
565  }
566 
567  //Loop through all the facets...
568  fEdgeFlag = true;
569 #ifndef G4OPENGL_VERSION_2
570  glBegin (GL_QUADS);
571  glEdgeFlag (GL_TRUE);
572 #else
573  fEmulate_GL_QUADS = true;
574  glBeginVBO(GL_TRIANGLE_STRIP);
575 #endif
576  G4bool notLastFace;
577  do {
578 
579  //First, find vertices, edgeflags and normals and note "not last facet"...
580  G4Point3D vertex[4];
581  G4int edgeFlag[4];
582  G4Normal3D normals[4];
583  G4int nEdges;
584  notLastFace = polyhedron.GetNextFacet(nEdges, vertex, edgeFlag, normals);
585 
586  //Loop through the four edges of each G4Facet...
587  for(G4int edgeCount = 0; edgeCount < nEdges; ++edgeCount) {
588  // Check to see if edge is visible or not...
589  if (isAuxEdgeVisible) {
590  edgeFlag[edgeCount] = 1;
591  }
592 #ifndef G4OPENGL_VERSION_2
593  if (edgeFlag[edgeCount] > 0) {
594  if (fEdgeFlag != true) {
595  glEdgeFlag (GL_TRUE);
596  fEdgeFlag = true;
597  }
598  } else {
599  if (fEdgeFlag != false) {
600  glEdgeFlag (GL_FALSE);
601  fEdgeFlag = false;
602  }
603  }
604  glNormal3d (normals[edgeCount].x(),
605  normals[edgeCount].y(),
606  normals[edgeCount].z());
607  glVertex3d (vertex[edgeCount].x(),
608  vertex[edgeCount].y(),
609  vertex[edgeCount].z());
610 #else
611 
612  fOglVertex.push_back(vertex[edgeCount].x());
613  fOglVertex.push_back(vertex[edgeCount].y());
614  fOglVertex.push_back(vertex[edgeCount].z());
615 
616  fOglVertex.push_back(normals[edgeCount].x());
617  fOglVertex.push_back(normals[edgeCount].y());
618  fOglVertex.push_back(normals[edgeCount].z());
619 
620 #endif
621 
622  }
623 
624  // HepPolyhedron produces triangles too; in that case add an extra
625  // vertex identical to first...
626  if (nEdges == 3) {
627  G4int edgeCount = 3;
628  normals[edgeCount] = normals[0];
629  vertex[edgeCount] = vertex[0];
630 #ifndef G4OPENGL_VERSION_2
631  edgeFlag[edgeCount] = -1;
632  if (fEdgeFlag != false) {
633  glEdgeFlag (GL_FALSE);
634  fEdgeFlag = false;
635  }
636 
637  glNormal3d (normals[edgeCount].x(),
638  normals[edgeCount].y(),
639  normals[edgeCount].z());
640  glVertex3d (vertex[edgeCount].x(),
641  vertex[edgeCount].y(),
642  vertex[edgeCount].z());
643 #else
644  fOglVertex.push_back(vertex[edgeCount].x());
645  fOglVertex.push_back(vertex[edgeCount].y());
646  fOglVertex.push_back(vertex[edgeCount].z());
647 
648  fOglVertex.push_back(normals[edgeCount].x());
649  fOglVertex.push_back(normals[edgeCount].y());
650  fOglVertex.push_back(normals[edgeCount].z());
651 
652 #endif
653  }
654  // Trap situation where number of edges is > 4...
655  if (nEdges > 4) {
656  G4cerr <<
657  "G4OpenGLSceneHandler::AddPrimitive(G4Polyhedron): WARNING"
658  "\n G4Polyhedron facet with " << nEdges << " edges" << G4endl;
659  }
660 
661 
662  // Do it all over again (twice) for hlr...
663  if (drawing_style == G4ViewParameters::hlr ||
664  drawing_style == G4ViewParameters::hlhsr) {
665 
666 #ifndef G4OPENGL_VERSION_2
667  glDisable(GL_COLOR_MATERIAL); // Revert to glMaterial for hlr/sr.
668 #endif
669 
670 #ifndef G4OPENGL_VERSION_2
671  glEnd (); // Placed here to balance glBegin above, allowing GL
672 #else
673  glEndVBO();
674 #endif
675  // state changes below, then glBegin again. Avoids
676  // having glBegin/End pairs *inside* loop in the more
677  // usual case of no hidden line removal.
678 
679  // Lighting disabled unless otherwise requested
680  glDisable (GL_LIGHTING);
681 
682  // Draw through stencil...
683  glStencilFunc (GL_EQUAL, 0, 1);
684  glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
685  if (drawing_style == G4ViewParameters::hlhsr) {
686  if (!fProcessing2D) glEnable (GL_LIGHTING);
687  }
688  glEnable (GL_DEPTH_TEST);
689  glDepthFunc (GL_LEQUAL);
690  if (isTransparent) {
691  // Transparent...
692  glDepthMask (GL_FALSE); // Make depth buffer read-only.
693  glDisable (GL_CULL_FACE);
694  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
695  } else {
696  // Opaque...
697  glDepthMask (GL_TRUE); // Make depth buffer writable (default).
698  if (clipping) {
699  glDisable (GL_CULL_FACE);
700  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
701  } else {
702  glEnable (GL_CULL_FACE);
703  glCullFace (GL_BACK);
704  glPolygonMode (GL_FRONT, GL_FILL);
705  }
706  }
707  if (drawing_style == G4ViewParameters::hlr) {
708  if (isTransparent) {
709  // Transparent - don't paint...
710  goto end_of_drawing_through_stencil;
711  }
712  }
713  if (isTransparent) {
714  // Transparent...
715  glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, painting_colour);
716  } else {
717  // Opaque...
718  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, painting_colour);
719  }
720  glColor4fv (painting_colour);
721 #ifndef G4OPENGL_VERSION_2
722  glBegin (GL_QUADS);
723  glEdgeFlag (GL_TRUE);
724  fEdgeFlag = true;
725 #else
726  fEmulate_GL_QUADS = true;
727  glBeginVBO(GL_TRIANGLE_STRIP);
728 #endif
729 
730  for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
731 #ifndef G4OPENGL_VERSION_2
732  if (edgeFlag[edgeCount] > 0) {
733  if (fEdgeFlag != true) {
734  glEdgeFlag (GL_TRUE);
735  fEdgeFlag = true;
736  }
737  } else {
738  if (fEdgeFlag != false) {
739  glEdgeFlag (GL_FALSE);
740  fEdgeFlag = false;
741  }
742  }
743  glNormal3d (normals[edgeCount].x(),
744  normals[edgeCount].y(),
745  normals[edgeCount].z());
746  glVertex3d (vertex[edgeCount].x(),
747  vertex[edgeCount].y(),
748  vertex[edgeCount].z());
749 #else
750 #ifdef G4DEBUG_VIS_OGL
751  printf(".....G4OpenGLSceneHandler::AddPrimitive polyhedron QUADS VBO 2\n");
752 #endif
753  fOglVertex.push_back(vertex[edgeCount].x());
754  fOglVertex.push_back(vertex[edgeCount].y());
755  fOglVertex.push_back(vertex[edgeCount].z());
756 
757  fOglVertex.push_back(normals[edgeCount].x());
758  fOglVertex.push_back(normals[edgeCount].y());
759  fOglVertex.push_back(normals[edgeCount].z());
760 
761 #endif
762  }
763 #ifndef G4OPENGL_VERSION_2
764  glEnd ();
765 #else
766  glEndVBO();
767 #endif
768  end_of_drawing_through_stencil:
769 
770  // and once more to reset the stencil bits...
771  glStencilFunc (GL_ALWAYS, 0, 1);
772  glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
773  glDepthFunc (GL_LEQUAL); // to make sure line gets drawn.
774  if (isTransparent) {
775  // Transparent...
776  glDisable (GL_CULL_FACE);
777  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
778  } else {
779  // Opaque...
780  if (clipping) {
781  glDisable (GL_CULL_FACE);
782  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
783  } else {
784  glEnable (GL_CULL_FACE);
785  glCullFace (GL_BACK);
786  glPolygonMode (GL_FRONT, GL_LINE);
787  }
788  }
789  glDisable (GL_LIGHTING);
790  glColor4fv (current_colour);
791  fEdgeFlag = true;
792 #ifndef G4OPENGL_VERSION_2
793  glBegin (GL_QUADS);
794  glEdgeFlag (GL_TRUE);
795  fEdgeFlag = true;
796 #else
797  fEmulate_GL_QUADS = true;
798  glBeginVBO(GL_TRIANGLE_STRIP);
799 #endif
800  for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
801 #ifndef G4OPENGL_VERSION_2
802  if (edgeFlag[edgeCount] > 0) {
803  if (fEdgeFlag != true) {
804  glEdgeFlag (GL_TRUE);
805  fEdgeFlag = true;
806  }
807  } else {
808  if (fEdgeFlag != false) {
809  glEdgeFlag (GL_FALSE);
810  fEdgeFlag = false;
811  }
812  }
813  glNormal3d (normals[edgeCount].x(),
814  normals[edgeCount].y(),
815  normals[edgeCount].z());
816  glVertex3d (vertex[edgeCount].x(),
817  vertex[edgeCount].y(),
818  vertex[edgeCount].z());
819 #else
820 #ifdef G4DEBUG_VIS_OGL
821  printf(".....G4OpenGLSceneHandler::AddPrimitive polyhedron QUADS VBO 3\n");
822 #endif
823  fOglVertex.push_back(vertex[edgeCount].x());
824  fOglVertex.push_back(vertex[edgeCount].y());
825  fOglVertex.push_back(vertex[edgeCount].z());
826 
827  fOglVertex.push_back(normals[edgeCount].x());
828  fOglVertex.push_back(normals[edgeCount].y());
829  fOglVertex.push_back(normals[edgeCount].z());
830 
831 #endif
832  }
833 #ifndef G4OPENGL_VERSION_2
834  glEnd ();
835 #else
836  glEndVBO();
837 #endif
838 
839  glDepthFunc (GL_LEQUAL); // Revert for next facet.
840  fEdgeFlag = true;
841 #ifndef G4OPENGL_VERSION_2
842  glBegin (GL_QUADS); // Ready for next facet. GL
843  glEdgeFlag (GL_TRUE);
844  fEdgeFlag = true;
845  // says it ignores incomplete
846  // quadrilaterals, so final empty
847  // glBegin/End sequence should be OK.
848 #else
849  fEmulate_GL_QUADS = true;
850  glBeginVBO(GL_TRIANGLE_STRIP);
851 #endif
852  }
853  } while (notLastFace);
854 
855 #ifndef G4OPENGL_VERSION_2
856  glEnd ();
857 #else
858 
859 // FIXME: du grand n'importe quoi en test
860 // Cube optimization
861 
862  // store old DrawType because in case of optimization it could be changed
863  GLenum oldDrawArrayType = fDrawArrayType;
864 
865  if (dynamic_cast<const G4PolyhedronTrd2*>(&polyhedron)) {
866 // OptimizeVBOForTrd();
867  } else if (dynamic_cast<const G4PolyhedronCons*>(&polyhedron)) {
868 // OptimizeVBOForCons((polyhedron.GetNoVertices()-2)/2 ); // top + bottom + all faces
869  }
870 
871  glEndVBO();
872  fDrawArrayType = oldDrawArrayType;
873 #endif
874 
875  glDisable (GL_STENCIL_TEST); // Revert to default for next primitive.
876  glDepthMask (GL_TRUE); // Revert to default for next primitive.
877 #ifndef G4OPENGL_VERSION_2
878  glDisable (GL_LIGHTING); // Revert to default for next primitive.
879 #endif
880 }
881 
882 void G4OpenGLSceneHandler::AddCompound(const G4VTrajectory& traj) {
883  G4VSceneHandler::AddCompound(traj); // For now.
884 }
885 
886 void G4OpenGLSceneHandler::AddCompound(const G4VHit& hit) {
887  G4VSceneHandler::AddCompound(hit); // For now.
888 }
889 
890 void G4OpenGLSceneHandler::AddCompound(const G4VDigi& digi) {
891  G4VSceneHandler::AddCompound(digi); // For now.
892 }
893 
894 void G4OpenGLSceneHandler::AddCompound(const G4THitsMap<G4double>& hits) {
895  G4VSceneHandler::AddCompound(hits); // For now.
896 }
897 
898 
899 #ifdef G4OPENGL_VERSION_2
900 
901 // Optimize vertex and indices in order to render less vertex in OpenGL VBO/IBO
902 void G4OpenGLSceneHandler::OptimizeVBOForTrd(){
903 
904  /* HOW IT IS BUILD (as we receive it from fOglVertex :
905  */
906 
907  std::vector<double> vertices;
908  vertices.insert (vertices.end(),fOglVertex.begin(),fOglVertex.begin()+6*6); // ABCDEF
909  vertices.insert (vertices.end(),fOglVertex.begin()+9*6,fOglVertex.begin()+9*6+6); // G
910  vertices.insert (vertices.end(),fOglVertex.begin()+13*6,fOglVertex.begin()+13*6+6); // H
911  fOglVertex = vertices;
912 
913  int myarray [] = {
914  3,2,0,1,4,5,7,6, 6,0,4,3,7,2,6,1,5
915  };
916  fOglIndices.insert(fOglIndices.begin(), myarray, myarray+17/*36*/);
917 
918  fDrawArrayType = GL_TRIANGLE_STRIP;
919 }
920 
921 // Optimize vertex and indices in order to render less vertex in OpenGL VBO/IBO
922 void G4OpenGLSceneHandler::OptimizeVBOForCons(G4int aNoFaces){
923  // Optimized, 1st level : 10f/15sec with 1000 cones
924  // DrawElements:208 vertex and 605 (2*100+2*100+2*100+5) indices for a 100 face cone
925 
926  /* surface of polycone : could be optimized
927  for 100 faces :
928  - 100*4 = 400 points
929  - 100*2+2 = 202 points with TRIANGLE_STRIP
930  Total :
931  n*4+n*4+n*4 = n*12
932  optimize : n*2+2+1+n+1 = n*3+3 (factor 4)
933  but could do better : n faces should give = n*2+2
934  */
935 
936  /*
937  0
938  / \
939  2---4 6 ....2
940  | |
941  3---5 7 ....3
942  \ /
943  1
944  */
945  // First, faces
946  std::vector<double> vertices;
947 
948  // Add bottom and top vertex
949  // aNoFaces*4*6+6 : nb Faces * 4 points per face * 6 vertex by point + 1 point offset
950  vertices.insert (vertices.end(),fOglVertex.begin()+ (aNoFaces*4)*6,fOglVertex.begin()+(aNoFaces*4)*6+6); // 0
951  vertices.insert (vertices.end(),fOglVertex.begin()+ (aNoFaces*8+1)*6,fOglVertex.begin()+(aNoFaces*8+1)*6+6); // 1
952 
953  // Add facets points
954  G4int posInVertice;
955  for (G4int a = 0; a<aNoFaces; a++) {
956  posInVertice = a*4*6;
957  vertices.insert (vertices.end(),fOglVertex.begin()+posInVertice,fOglVertex.begin()+posInVertice+1*6+6); // AB
958  }
959  vertices.insert (vertices.end(),fOglVertex.begin(),fOglVertex.begin()+1*6*6); // AB
960  fOglVertex = vertices;
961 
962  // Add indices for top :
963  // simple version : 0-2-0-4-0-6-0-8-0-10..
964  // optimized version : 2-0-4-6- 6-0-8-10.. but we have to deal with odd faces numbers
965  for (G4int a=0; a<aNoFaces; a++) {
966  fOglIndices.push_back(0);
967  fOglIndices.push_back(a*2+2);
968  }
969  // close strip
970  fOglIndices.push_back(0);
971  fOglIndices.push_back(2);
972 
973  // Add indices for faces
974  for (G4int a = 0; a<aNoFaces; a++) {
975  fOglIndices.push_back(a*2+2);
976  fOglIndices.push_back(a*2+1+2);
977  }
978  fOglIndices.push_back(2);
979  fOglIndices.push_back(2+1);
980 
981  // Second : top
982  // 3-1-5-1-7-1-9-1..
983  for (G4int a=0; a<aNoFaces; a++) {
984  fOglIndices.push_back(a*2+3);
985  fOglIndices.push_back(1);
986  }
987  // close strip
988  fOglIndices.push_back(0+3);
989 
990  fDrawArrayType = GL_TRIANGLE_STRIP;
991  fEmulate_GL_QUADS = false;
992 }
993 
994 void G4OpenGLSceneHandler::glBeginVBO(GLenum type) {
995  fDrawArrayType = type;
996 #ifdef G4DEBUG_VIS_OGL
997  printf("G4OpenGLSceneHandler::glBeginVBO %d\n",type);
998 #endif
999 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1000  glGenBuffers(1,&fVertexBufferObject);
1001  glGenBuffers(1,&fIndicesBufferObject);
1002 #else
1003  fVertexBufferObject = glCreateBuffer(); //glGenBuffer(1,fVertexBufferObject_2)
1004  fIndicesBufferObject = glCreateBuffer(); //glGenBuffer(1,fIndicesBufferObject_2)
1005 #endif
1006 
1007  // clear data and indices for OpenGL
1008  fOglVertex.clear();
1009  fOglIndices.clear();
1010 }
1011 
1012 // 2 cases :
1013 /*
1014  glDrawArray : if there is no vertex indices : fOglIndices.size() == 0
1015  glDrawElements : if there is vertex indices : fOglIndices.size() != 0
1016 
1017  */
1018 void G4OpenGLSceneHandler::glEndVBO() {
1019  if (fOglIndices.size() == 0) {
1020 
1021 
1022  std::vector<double> vertices;
1023  // check if it is a GL_QUADS emulation
1024  if (fEmulate_GL_QUADS == true) {
1025  fEmulate_GL_QUADS = false;
1026  // A point has 6 double : Vx Vy Vz Nx Ny Nz
1027  // A QUAD should be like this
1028  /*
1029  0 3/4 7/8 ..
1030 
1031  1 2/5 6/9 ..
1032  */
1033  // And if 3==4 and 2==5, we should do it like this for a TRIANGLES_STRIP
1034  /*
1035  0 4 8 ..
1036  | / | / |
1037  1 5 9 ..
1038  // Optimized, 1st level : 24f/15sec with 10 cones
1039  // non Optimized, 1st level : 12f/15sec with 10 cones
1040  */
1041  // should be 4 points
1042  for (unsigned int a=0; a<fOglVertex.size(); a+=6*4) {
1043  vertices.insert (vertices.end(),fOglVertex.begin()+a,fOglVertex.begin()+a+1*6+6); // 0-1
1044  // if 2-3 == 4-5, do not add them
1045  // if differents, we are obliged to create a new GL_TRIANGLE_STRIP
1046  if (a+4*6+5 < fOglVertex.size()) {
1047  if ((fOglVertex[a+2*6+0] != fOglVertex[a+5*6+0]) || //Vx for 2 and 5
1048  (fOglVertex[a+2*6+1] != fOglVertex[a+5*6+1]) || //Vy for 2 and 5
1049  (fOglVertex[a+2*6+2] != fOglVertex[a+5*6+2]) || //Vz for 2 and 5
1050  (fOglVertex[a+2*6+3] != fOglVertex[a+5*6+3]) || //Px for 2 and 5
1051  (fOglVertex[a+2*6+4] != fOglVertex[a+5*6+4]) || //Py for 2 and 5
1052  (fOglVertex[a+2*6+5] != fOglVertex[a+5*6+5]) || //Pz for 2 and 5
1053 
1054  (fOglVertex[a+3*6+0] != fOglVertex[a+4*6+0]) || //Vx for 3 and 4
1055  (fOglVertex[a+3*6+1] != fOglVertex[a+4*6+1]) || //Vy for 3 and 4
1056  (fOglVertex[a+3*6+2] != fOglVertex[a+4*6+2]) || //Vz for 3 and 4
1057  (fOglVertex[a+3*6+3] != fOglVertex[a+4*6+3]) || //Px for 3 and 4
1058  (fOglVertex[a+3*6+4] != fOglVertex[a+4*6+4]) || //Py for 3 and 4
1059  (fOglVertex[a+3*6+5] != fOglVertex[a+4*6+5])) { //Pz for 3 and 4
1060  // add last points
1061  vertices.insert (vertices.end(),fOglVertex.begin()+a+3*6,fOglVertex.begin()+a+3*6+6); // 3
1062  vertices.insert (vertices.end(),fOglVertex.begin()+a+2*6,fOglVertex.begin()+a+2*6+6); // 2
1063  // build and send the GL_TRIANGLE_STRIP
1064  drawVBOArray(vertices);
1065  vertices.clear();
1066  }
1067  } else { // end of volume
1068  vertices.insert (vertices.end(),fOglVertex.begin()+a+3*6,fOglVertex.begin()+a+3*6+6); // 3
1069  vertices.insert (vertices.end(),fOglVertex.begin()+a+2*6,fOglVertex.begin()+a+2*6+6); // 2
1070  }
1071  }
1072  fOglVertex = vertices;
1073  }
1074 
1075  drawVBOArray(fOglVertex);
1076 
1077  } else {
1078 
1079  // Bind VBO
1080  glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject);
1081 
1082  // Load fOglVertex into VBO
1083 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1084  int sizeV = fOglVertex.size();
1085  // FIXME : perhaps a problem withBufferData in OpenGL other than WebGL ?
1086 // void glBufferData( GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
1087  glBufferData(GL_ARRAY_BUFFER, sizeof(double)*sizeV, &fOglVertex[0], GL_STATIC_DRAW);
1088 #else
1089  glBufferDatafv(GL_ARRAY_BUFFER, fOglVertex.begin(), fOglVertex.end(), GL_STATIC_DRAW);
1090 #endif
1091 
1092  // Bind IBO
1093  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fIndicesBufferObject);
1094 
1095  // Load fOglVertex into VBO
1096 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1097  int sizeI = fOglIndices.size();
1098  glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(int)*sizeI, &fOglIndices[0], GL_STATIC_DRAW);
1099 #else
1100  glBufferDataiv(GL_ELEMENT_ARRAY_BUFFER, fOglIndices.begin(), fOglIndices.end(), GL_STATIC_DRAW, GL_UNSIGNED_BYTE);
1101 #endif
1102 
1103  //----------------------------
1104  // Draw VBO
1105  //----------------------------
1106  glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject);
1107  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fIndicesBufferObject);
1108 
1109 #ifdef G4DEBUG_VIS_OGL
1110  printf("G4OpenGLSceneHandler::glEndVBO() To DrawElements:%d vertex and %d indices\n",fOglVertex.size()/6,fOglIndices.size());
1111 #endif
1112 
1113  // the fVertexPositionAttribute is inside the G4OpenGLViewer
1114  G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
1115  if (pGLViewer) {
1116  glEnableVertexAttribArray(pGLViewer->fVertexPositionAttribute);
1117 
1118  glVertexAttribPointer(pGLViewer->fVertexPositionAttribute,
1119  3, // size: Every vertex has an X, Y anc Z component
1120  GL_FLOAT, // type: They are floats
1121  GL_FALSE, // normalized: Please, do NOT normalize the vertices
1122  2*3*4, // stride: The first byte of the next vertex is located this
1123  // amount of bytes further. The format of the VBO is
1124  // vx, vy, vz, nx, ny, nz and every element is a
1125  // Float32, hence 4 bytes large
1126  0); // offset: The byte position of the first vertex in the buffer
1127  }
1128 
1129 
1130  glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject);
1131  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fIndicesBufferObject);
1132 // glDrawElements(fDrawArrayType, fOglIndices.size(), GL_UNSIGNED_SHORT, 0);
1133  glDrawElements(fDrawArrayType, fOglIndices.size(), GL_UNSIGNED_SHORT, 0);
1134 
1135  if (pGLViewer) {
1136  glDisableVertexAttribArray(pGLViewer->fVertexPositionAttribute);
1137  }
1138 
1139  // delete the buffer
1140 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1141  glDeleteBuffers(1,&fVertexBufferObject);
1142 #else
1143  glDeleteBuffer(fVertexBufferObject);
1144 #endif
1145  }
1146 }
1147 
1148 void G4OpenGLSceneHandler::drawVBOArray(std::vector<double> vertices) {
1149 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1150  glGenBuffers(1,&fVertexBufferObject);
1151  glGenBuffers(1,&fIndicesBufferObject);
1152 #else
1153  fVertexBufferObject = glCreateBuffer(); //glGenBuffer(1,fVertexBufferObject_2)
1154  fIndicesBufferObject = glCreateBuffer(); //glGenBuffer(1,fIndicesBufferObject_2)
1155 #endif
1156 
1157  // Bind this buffer
1158  glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject);
1159  // Load oglData into VBO
1160 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1161  int s = vertices.size();
1162  glBufferData(GL_ARRAY_BUFFER, sizeof(double)*s, &vertices[0], GL_STATIC_DRAW);
1163 #else
1164  glBufferDatafv(GL_ARRAY_BUFFER, vertices.begin(), vertices.end(), GL_STATIC_DRAW);
1165 #endif
1166 
1167  //----------------------------
1168  // Draw VBO
1169  //----------------------------
1170  glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject);
1171 
1172  // the fVertexPositionAttribute is inside the G4OpenGLViewer
1173  G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
1174  if (pGLViewer) {
1175  glEnableVertexAttribArray(pGLViewer->fVertexPositionAttribute);
1176 
1177 // glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer)
1178 
1179 /*
1180  GL_DOUBLE
1181  Warning: This section describes legacy OpenGL APIs that have been removed from core OpenGL 3.1 and above (they are only deprecated in OpenGL 3.0). It is recommended that you not use this functionality in your programs.
1182 
1183  glLoadMatrixd, glRotated and any other function that have to do with the double type. Most GPUs don't support GL_DOUBLE (double) so the driver will convert the data to GL_FLOAT (float) and send to the GPU. If you put GL_DOUBLE data in a VBO, the performance might even be much worst than immediate mode (immediate mode means glBegin, glVertex, glEnd). GL doesn't offer any better way to know what the GPU prefers.
1184  */
1185 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1186  glVertexAttribPointer(pGLViewer->fVertexPositionAttribute,
1187  3, // size: Every vertex has an X, Y anc Z component
1188  GL_DOUBLE, // type: They are double
1189  GL_FALSE, // normalized: Please, do NOT normalize the vertices
1190  6*sizeof(double), // stride: The first byte of the next vertex is located this
1191  // amount of bytes further. The format of the VBO is
1192  // vx, vy, vz, nx, ny, nz and every element is a
1193  // Float32, hence 4 bytes large
1194  0); // offset: The byte position of the first vertex in the buffer
1195 #else
1196  glVertexAttribPointer(pGLViewer->fVertexPositionAttribute,
1197  3, // size: Every vertex has an X, Y anc Z component
1198  GL_FLOAT, // type: They are floats
1199  GL_FALSE, // normalized: Please, do NOT normalize the vertices
1200  2*3*4, // stride: The first byte of the next vertex is located this
1201  // amount of bytes further. The format of the VBO is
1202  // vx, vy, vz, nx, ny, nz and every element is a
1203  // Float32, hence 4 bytes large
1204  0); // offset: The byte position of the first vertex in the buffer
1205 #endif
1206  }
1207 
1208  glDrawArrays(fDrawArrayType, // GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP, and GL_TRIANGLES
1209  0, vertices.size()/6);
1210  if (pGLViewer) {
1211 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1212  glDisableClientState( GL_VERTEX_ARRAY );
1213 #else
1214  glDisableVertexAttribArray(pGLViewer->fVertexPositionAttribute);
1215 #endif
1216  }
1217 
1218  // delet the buffer
1219 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1220  glDeleteBuffers(1,&fVertexBufferObject);
1221 #else
1222  glDeleteBuffer(fVertexBufferObject);
1223 #endif
1224 }
1225 #endif
1226 
1227 
1228 #endif
Definition: G4Text.hh:73
virtual G4VSolid * CreateSectionSolid()
MarkerType GetMarkerType() const
virtual void BeginPrimitives(const G4Transform3D &objectTransformation)
G4double z
Definition: TRTMaterials.hh:39
G4String name
Definition: TRTMaterials.hh:40
const G4double pi
HepGeom::Point3D< G4double > G4Point3D
Definition: G4Point3D.hh:35
HepGeom::Vector3D< G4double > G4Vector3D
Definition: G4Vector3D.hh:35
Definition: G4VHit.hh:48
G4double a
Definition: TRTMaterials.hh:39
G4Point3D GetPosition() const
const G4VisAttributes * GetVisAttributes() const
int G4int
Definition: G4Types.hh:78
virtual void AddPrimitive(const G4Polyline &)=0
virtual G4VSolid * CreateCutawaySolid()
static const double s
Definition: G4SIunits.hh:150
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
virtual void EndPrimitives()
HepGeom::Transform3D G4Transform3D
virtual void BeginPrimitives2D(const G4Transform3D &objectTransformation)
virtual void AddCompound(const G4VTrajectory &)
virtual void ProcessScene()
virtual void PreAddSolid(const G4Transform3D &objectTransformation, const G4VisAttributes &)
FillStyle GetFillStyle() const
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
virtual void EndPrimitives2D()
G4GLOB_DLL std::ostream G4cerr
HepGeom::Normal3D< G4double > G4Normal3D
Definition: G4Normal3D.hh:35