Geant4  10.02.p01
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 91686 2015-07-31 09:40:08Z 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  fOglVertex.push_back(p.x());
352  fOglVertex.push_back(p.y());
353  fOglVertex.push_back(p.z());
354  // normal
355  fOglVertex.push_back(0);
356  fOglVertex.push_back(0);
357  fOglVertex.push_back(1);
358  }
359  glEndVBO ();
360 #endif
361  }
362 
363  } else { // Size specified in screen (window) coordinates.
364 
365  pGLViewer->ChangePointSize(size);
366 
367  //Antialiasing only for circles
368 #ifndef G4OPENGL_VERSION_2
369  switch (polymarker.GetMarkerType()) {
370  default:
371  case G4Polymarker::dots:
373  glEnable (GL_POINT_SMOOTH); break;
375  glDisable (GL_POINT_SMOOTH); break;
376  }
377 #endif
378 #ifndef G4OPENGL_VERSION_2
379  glBegin (GL_POINTS);
380  for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
381  G4Point3D centre = polymarker[iPoint];
382  glVertex3d(centre.x(),centre.y(),centre.z());
383  }
384  glEnd();
385 #else
386  glBeginVBO(GL_POINTS);
387 
388  for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
389  fOglVertex.push_back(polymarker[iPoint].x());
390  fOglVertex.push_back(polymarker[iPoint].y());
391  fOglVertex.push_back(polymarker[iPoint].z());
392  fOglVertex.push_back(0);
393  fOglVertex.push_back(0);
394  fOglVertex.push_back(1);
395  }
396  glEndVBO();
397 #endif
398  }
399 }
400 
401 void G4OpenGLSceneHandler::AddPrimitive (const G4Text& text) {
402  // Pass to specific viewer via virtual function DrawText.
403  // FIXME : Not ready for OPENGL2 for the moment
404 #ifdef G4OPENGL_VERSION_2
405  return;
406 #endif
407  G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
408  if (pGLViewer) pGLViewer->DrawText(text);
409 }
410 
411 void G4OpenGLSceneHandler::AddPrimitive (const G4Circle& circle) {
412  G4Polymarker oneCircle(circle);
413  oneCircle.push_back(circle.GetPosition());
414  oneCircle.SetMarkerType(G4Polymarker::circles);
415  // Call this AddPrimitive to avoid re-doing sub-class code.
416  G4OpenGLSceneHandler::AddPrimitive(oneCircle);
417 }
418 
419 void G4OpenGLSceneHandler::AddPrimitive (const G4Square& square) {
420  G4Polymarker oneSquare(square);
421  oneSquare.push_back(square.GetPosition());
422  oneSquare.SetMarkerType(G4Polymarker::squares);
423  // Call this AddPrimitive to avoid re-doing sub-class code.
424  G4OpenGLSceneHandler::AddPrimitive(oneSquare);
425 }
426 
427 void G4OpenGLSceneHandler::AddPrimitive (const G4Scale& scale)
428 {
430 }
431 
432 //Method for handling G4Polyhedron objects for drawing solids.
433 void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
434 
435  // Assume all facets are planar convex quadrilaterals.
436  // Draw each facet individually
437 
438  if (polyhedron.GetNoFacets() == 0) return;
439 
440  // Need access to data in G4OpenGLViewer. static_cast doesn't work
441  // with a virtual base class, so use dynamic_cast.
442  G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
443  if (!pGLViewer) return;
444 
445  // Get vis attributes - pick up defaults if none.
446  const G4VisAttributes* pVA =
447  fpViewer -> GetApplicableVisAttributes (polyhedron.GetVisAttributes ());
448 
449  // Get view parameters that the user can force through the vis
450  // attributes, thereby over-riding the current view parameter.
451  G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
452 
453  // Note that in stored mode, because this call gets embedded in a display
454  // list, it is the colour _at the time of_ creation of the display list, so
455  // even if the colour is changed, for example, by interaction with a Qt
456  // window, current_colour does not change.
457  GLfloat* painting_colour;
458  GLfloat current_colour [4];
459  glGetFloatv (GL_CURRENT_COLOR, current_colour);
460 
461  G4bool isTransparent = false;
462  if (current_colour[3] < 1.) { // This object is transparent
463  isTransparent = true;
464  }
465 
466 
467  if (drawing_style == G4ViewParameters::hlr) {
468  // This is the colour used to paint surfaces in hlr mode.
469  GLfloat clear_colour[4];
470  glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour);
471  painting_colour = clear_colour;
472  } else { // drawing_style == G4ViewParameters::hlhsr
473  painting_colour = current_colour;
474  }
475 
476  G4double lineWidth = GetLineWidth(pVA);
477  pGLViewer->ChangeLineWidth(lineWidth);
478 
479  G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
480 
481  G4bool clipping = pGLViewer->fVP.IsSection() || pGLViewer->fVP.IsCutaway();
482 
483  // Lighting disabled unless otherwise requested
484 #ifndef G4OPENGL_VERSION_2
485  glDisable (GL_LIGHTING);
486 #endif
487 
488  switch (drawing_style) {
490  // Set up as for hidden line removal but paint polygon faces later...
491  case (G4ViewParameters::hlr):
492  glEnable (GL_STENCIL_TEST);
493  // The stencil buffer is cleared in G4OpenGLViewer::ClearView.
494  // The procedure below leaves it clear.
495  glStencilFunc (GL_ALWAYS, 0, 1);
496  glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
497  glEnable (GL_DEPTH_TEST);
498  glDepthFunc (GL_LEQUAL);
499  if (isTransparent) {
500  // Transparent...
501  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
502  glEnable(GL_COLOR_MATERIAL);
503  glDisable (GL_CULL_FACE);
504  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
505  } else {
506  // Opaque...
507  if (clipping) {
508  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
509  glEnable(GL_COLOR_MATERIAL);
510  glDisable (GL_CULL_FACE);
511  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
512  } else {
513  glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
514  glEnable(GL_COLOR_MATERIAL);
515  glEnable (GL_CULL_FACE);
516  glCullFace (GL_BACK);
517  glPolygonMode (GL_FRONT, GL_LINE);
518  }
519  }
520  break;
521  case (G4ViewParameters::hsr):
522  glEnable (GL_DEPTH_TEST);
523  glDepthFunc (GL_LEQUAL);
524  if (isTransparent) {
525  // Transparent...
526  glDepthMask (GL_FALSE); // Make depth buffer read-only.
527  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
528 #ifndef G4OPENGL_VERSION_2
529  glEnable(GL_COLOR_MATERIAL);
530 #endif
531  glDisable (GL_CULL_FACE);
532  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
533  } else {
534  // Opaque...
535  glDepthMask (GL_TRUE); // Make depth buffer writable (default).
536  if (clipping) {
537  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
538  glEnable(GL_COLOR_MATERIAL);
539  glDisable (GL_CULL_FACE);
540  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
541  } else {
542  glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
543 #ifndef G4OPENGL_VERSION_2
544  glEnable(GL_COLOR_MATERIAL);
545 #endif
546  glEnable (GL_CULL_FACE);
547  glCullFace (GL_BACK);
548  glPolygonMode (GL_FRONT, GL_FILL);
549  }
550  }
551 #ifndef G4OPENGL_VERSION_2
552  if (!fProcessing2D) glEnable (GL_LIGHTING);
553 #endif
554  break;
556  default:
557  glEnable (GL_DEPTH_TEST);
558  glDepthFunc (GL_LEQUAL); //??? was GL_ALWAYS
559  glDisable (GL_CULL_FACE);
560  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
561  break;
562  }
563 
564  //Loop through all the facets...
565  fEdgeFlag = true;
566 #ifndef G4OPENGL_VERSION_2
567  glBegin (GL_QUADS);
568  glEdgeFlag (GL_TRUE);
569 #else
570  fEmulate_GL_QUADS = true;
571  glBeginVBO(GL_TRIANGLE_STRIP);
572 #endif
573  G4bool notLastFace;
574  do {
575 
576  //First, find vertices, edgeflags and normals and note "not last facet"...
577  G4Point3D vertex[4];
578  G4int edgeFlag[4];
579  G4Normal3D normals[4];
580  G4int nEdges;
581  notLastFace = polyhedron.GetNextFacet(nEdges, vertex, edgeFlag, normals);
582 
583  //Loop through the four edges of each G4Facet...
584  for(G4int edgeCount = 0; edgeCount < nEdges; ++edgeCount) {
585  // Check to see if edge is visible or not...
586  if (isAuxEdgeVisible) {
587  edgeFlag[edgeCount] = 1;
588  }
589 #ifndef G4OPENGL_VERSION_2
590  if (edgeFlag[edgeCount] > 0) {
591  if (fEdgeFlag != true) {
592  glEdgeFlag (GL_TRUE);
593  fEdgeFlag = true;
594  }
595  } else {
596  if (fEdgeFlag != false) {
597  glEdgeFlag (GL_FALSE);
598  fEdgeFlag = false;
599  }
600  }
601  glNormal3d (normals[edgeCount].x(),
602  normals[edgeCount].y(),
603  normals[edgeCount].z());
604  glVertex3d (vertex[edgeCount].x(),
605  vertex[edgeCount].y(),
606  vertex[edgeCount].z());
607 #else
608 
609  fOglVertex.push_back(vertex[edgeCount].x());
610  fOglVertex.push_back(vertex[edgeCount].y());
611  fOglVertex.push_back(vertex[edgeCount].z());
612 
613  fOglVertex.push_back(normals[edgeCount].x());
614  fOglVertex.push_back(normals[edgeCount].y());
615  fOglVertex.push_back(normals[edgeCount].z());
616 
617 #endif
618 
619  }
620 
621  // HepPolyhedron produces triangles too; in that case add an extra
622  // vertex identical to first...
623  if (nEdges == 3) {
624  G4int edgeCount = 3;
625  normals[edgeCount] = normals[0];
626  vertex[edgeCount] = vertex[0];
627 #ifndef G4OPENGL_VERSION_2
628  edgeFlag[edgeCount] = -1;
629  if (fEdgeFlag != false) {
630  glEdgeFlag (GL_FALSE);
631  fEdgeFlag = false;
632  }
633 
634  glNormal3d (normals[edgeCount].x(),
635  normals[edgeCount].y(),
636  normals[edgeCount].z());
637  glVertex3d (vertex[edgeCount].x(),
638  vertex[edgeCount].y(),
639  vertex[edgeCount].z());
640 #else
641  fOglVertex.push_back(vertex[edgeCount].x());
642  fOglVertex.push_back(vertex[edgeCount].y());
643  fOglVertex.push_back(vertex[edgeCount].z());
644 
645  fOglVertex.push_back(normals[edgeCount].x());
646  fOglVertex.push_back(normals[edgeCount].y());
647  fOglVertex.push_back(normals[edgeCount].z());
648 
649 #endif
650  }
651  // Trap situation where number of edges is > 4...
652  if (nEdges > 4) {
653  G4cerr <<
654  "G4OpenGLSceneHandler::AddPrimitive(G4Polyhedron): WARNING"
655  "\n G4Polyhedron facet with " << nEdges << " edges" << G4endl;
656  }
657 
658 
659  // Do it all over again (twice) for hlr...
660  if (drawing_style == G4ViewParameters::hlr ||
661  drawing_style == G4ViewParameters::hlhsr) {
662 
663 #ifndef G4OPENGL_VERSION_2
664  glDisable(GL_COLOR_MATERIAL); // Revert to glMaterial for hlr/sr.
665 #endif
666 
667 #ifndef G4OPENGL_VERSION_2
668  glEnd (); // Placed here to balance glBegin above, allowing GL
669 #else
670  glEndVBO();
671 #endif
672  // state changes below, then glBegin again. Avoids
673  // having glBegin/End pairs *inside* loop in the more
674  // usual case of no hidden line removal.
675 
676  // Lighting disabled unless otherwise requested
677  glDisable (GL_LIGHTING);
678 
679  // Draw through stencil...
680  glStencilFunc (GL_EQUAL, 0, 1);
681  glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
682  if (drawing_style == G4ViewParameters::hlhsr) {
683  if (!fProcessing2D) glEnable (GL_LIGHTING);
684  }
685  glEnable (GL_DEPTH_TEST);
686  glDepthFunc (GL_LEQUAL);
687  if (isTransparent) {
688  // Transparent...
689  glDepthMask (GL_FALSE); // Make depth buffer read-only.
690  glDisable (GL_CULL_FACE);
691  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
692  } else {
693  // Opaque...
694  glDepthMask (GL_TRUE); // Make depth buffer writable (default).
695  if (clipping) {
696  glDisable (GL_CULL_FACE);
697  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
698  } else {
699  glEnable (GL_CULL_FACE);
700  glCullFace (GL_BACK);
701  glPolygonMode (GL_FRONT, GL_FILL);
702  }
703  }
704  if (drawing_style == G4ViewParameters::hlr) {
705  if (isTransparent) {
706  // Transparent - don't paint...
707  goto end_of_drawing_through_stencil;
708  }
709  }
710  if (isTransparent) {
711  // Transparent...
712  glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, painting_colour);
713  } else {
714  // Opaque...
715  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, painting_colour);
716  }
717  glColor4fv (painting_colour);
718 #ifndef G4OPENGL_VERSION_2
719  glBegin (GL_QUADS);
720  glEdgeFlag (GL_TRUE);
721  fEdgeFlag = true;
722 #else
723  fEmulate_GL_QUADS = true;
724  glBeginVBO(GL_TRIANGLE_STRIP);
725 #endif
726 
727  for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
728 #ifndef G4OPENGL_VERSION_2
729  if (edgeFlag[edgeCount] > 0) {
730  if (fEdgeFlag != true) {
731  glEdgeFlag (GL_TRUE);
732  fEdgeFlag = true;
733  }
734  } else {
735  if (fEdgeFlag != false) {
736  glEdgeFlag (GL_FALSE);
737  fEdgeFlag = false;
738  }
739  }
740  glNormal3d (normals[edgeCount].x(),
741  normals[edgeCount].y(),
742  normals[edgeCount].z());
743  glVertex3d (vertex[edgeCount].x(),
744  vertex[edgeCount].y(),
745  vertex[edgeCount].z());
746 #else
747  fOglVertex.push_back(vertex[edgeCount].x());
748  fOglVertex.push_back(vertex[edgeCount].y());
749  fOglVertex.push_back(vertex[edgeCount].z());
750 
751  fOglVertex.push_back(normals[edgeCount].x());
752  fOglVertex.push_back(normals[edgeCount].y());
753  fOglVertex.push_back(normals[edgeCount].z());
754 
755 #endif
756  }
757 #ifndef G4OPENGL_VERSION_2
758  glEnd ();
759 #else
760  glEndVBO();
761 #endif
762  end_of_drawing_through_stencil:
763 
764  // and once more to reset the stencil bits...
765  glStencilFunc (GL_ALWAYS, 0, 1);
766  glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
767  glDepthFunc (GL_LEQUAL); // to make sure line gets drawn.
768  if (isTransparent) {
769  // Transparent...
770  glDisable (GL_CULL_FACE);
771  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
772  } else {
773  // Opaque...
774  if (clipping) {
775  glDisable (GL_CULL_FACE);
776  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
777  } else {
778  glEnable (GL_CULL_FACE);
779  glCullFace (GL_BACK);
780  glPolygonMode (GL_FRONT, GL_LINE);
781  }
782  }
783  glDisable (GL_LIGHTING);
784  glColor4fv (current_colour);
785  fEdgeFlag = true;
786 #ifndef G4OPENGL_VERSION_2
787  glBegin (GL_QUADS);
788  glEdgeFlag (GL_TRUE);
789  fEdgeFlag = true;
790 #else
791  fEmulate_GL_QUADS = true;
792  glBeginVBO(GL_TRIANGLE_STRIP);
793 #endif
794  for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
795 #ifndef G4OPENGL_VERSION_2
796  if (edgeFlag[edgeCount] > 0) {
797  if (fEdgeFlag != true) {
798  glEdgeFlag (GL_TRUE);
799  fEdgeFlag = true;
800  }
801  } else {
802  if (fEdgeFlag != false) {
803  glEdgeFlag (GL_FALSE);
804  fEdgeFlag = false;
805  }
806  }
807  glNormal3d (normals[edgeCount].x(),
808  normals[edgeCount].y(),
809  normals[edgeCount].z());
810  glVertex3d (vertex[edgeCount].x(),
811  vertex[edgeCount].y(),
812  vertex[edgeCount].z());
813 #else
814  fOglVertex.push_back(vertex[edgeCount].x());
815  fOglVertex.push_back(vertex[edgeCount].y());
816  fOglVertex.push_back(vertex[edgeCount].z());
817 
818  fOglVertex.push_back(normals[edgeCount].x());
819  fOglVertex.push_back(normals[edgeCount].y());
820  fOglVertex.push_back(normals[edgeCount].z());
821 
822 #endif
823  }
824 #ifndef G4OPENGL_VERSION_2
825  glEnd ();
826 #else
827  glEndVBO();
828 #endif
829 
830  glDepthFunc (GL_LEQUAL); // Revert for next facet.
831  fEdgeFlag = true;
832 #ifndef G4OPENGL_VERSION_2
833  glBegin (GL_QUADS); // Ready for next facet. GL
834  glEdgeFlag (GL_TRUE);
835  fEdgeFlag = true;
836  // says it ignores incomplete
837  // quadrilaterals, so final empty
838  // glBegin/End sequence should be OK.
839 #else
840  fEmulate_GL_QUADS = true;
841  glBeginVBO(GL_TRIANGLE_STRIP);
842 #endif
843  }
844  } while (notLastFace);
845 
846 #ifndef G4OPENGL_VERSION_2
847  glEnd ();
848 #else
849 
850 // FIXME: du grand n'importe quoi en test
851 // Cube optimization
852 
853  // store old DrawType because in case of optimization it could be changed
854  GLenum oldDrawArrayType = fDrawArrayType;
855 
856  if (dynamic_cast<const G4PolyhedronTrd2*>(&polyhedron)) {
857 // OptimizeVBOForTrd();
858  } else if (dynamic_cast<const G4PolyhedronCons*>(&polyhedron)) {
859 // OptimizeVBOForCons((polyhedron.GetNoVertices()-2)/2 ); // top + bottom + all faces
860  }
861 
862  glEndVBO();
863  fDrawArrayType = oldDrawArrayType;
864 #endif
865 
866  glDisable (GL_STENCIL_TEST); // Revert to default for next primitive.
867  glDepthMask (GL_TRUE); // Revert to default for next primitive.
868 #ifndef G4OPENGL_VERSION_2
869  glDisable (GL_LIGHTING); // Revert to default for next primitive.
870 #endif
871 }
872 
873 void G4OpenGLSceneHandler::AddCompound(const G4VTrajectory& traj) {
874  G4VSceneHandler::AddCompound(traj); // For now.
875 }
876 
877 void G4OpenGLSceneHandler::AddCompound(const G4VHit& hit) {
878  G4VSceneHandler::AddCompound(hit); // For now.
879 }
880 
881 void G4OpenGLSceneHandler::AddCompound(const G4VDigi& digi) {
882  G4VSceneHandler::AddCompound(digi); // For now.
883 }
884 
885 void G4OpenGLSceneHandler::AddCompound(const G4THitsMap<G4double>& hits) {
886  G4VSceneHandler::AddCompound(hits); // For now.
887 }
888 
889 
890 #ifdef G4OPENGL_VERSION_2
891 
892 // Optimize vertex and indices in order to render less vertex in OpenGL VBO/IBO
893 void G4OpenGLSceneHandler::OptimizeVBOForTrd(){
894 
895  /* HOW IT IS BUILD (as we receive it from fOglVertex :
896  */
897 
898  std::vector<double> vertices;
899  vertices.insert (vertices.end(),fOglVertex.begin(),fOglVertex.begin()+6*6); // ABCDEF
900  vertices.insert (vertices.end(),fOglVertex.begin()+9*6,fOglVertex.begin()+9*6+6); // G
901  vertices.insert (vertices.end(),fOglVertex.begin()+13*6,fOglVertex.begin()+13*6+6); // H
902  fOglVertex = vertices;
903 
904  int myarray [] = {
905  3,2,0,1,4,5,7,6, 6,0,4,3,7,2,6,1,5
906  };
907  fOglIndices.insert(fOglIndices.begin(), myarray, myarray+17/*36*/);
908 
909  fDrawArrayType = GL_TRIANGLE_STRIP;
910 }
911 
912 // Optimize vertex and indices in order to render less vertex in OpenGL VBO/IBO
913 void G4OpenGLSceneHandler::OptimizeVBOForCons(G4int aNoFaces){
914  // Optimized, 1st level : 10f/15sec with 1000 cones
915  // DrawElements:208 vertex and 605 (2*100+2*100+2*100+5) indices for a 100 face cone
916 
917  /* surface of polycone : could be optimized
918  for 100 faces :
919  - 100*4 = 400 points
920  - 100*2+2 = 202 points with TRIANGLE_STRIP
921  Total :
922  n*4+n*4+n*4 = n*12
923  optimize : n*2+2+1+n+1 = n*3+3 (factor 4)
924  but could do better : n faces should give = n*2+2
925  */
926 
927  /*
928  0
929  / \
930  2---4 6 ....2
931  | |
932  3---5 7 ....3
933  \ /
934  1
935  */
936  // First, faces
937  std::vector<double> vertices;
938 
939  // Add bottom and top vertex
940  // aNoFaces*4*6+6 : nb Faces * 4 points per face * 6 vertex by point + 1 point offset
941  vertices.insert (vertices.end(),fOglVertex.begin()+ (aNoFaces*4)*6,fOglVertex.begin()+(aNoFaces*4)*6+6); // 0
942  vertices.insert (vertices.end(),fOglVertex.begin()+ (aNoFaces*8+1)*6,fOglVertex.begin()+(aNoFaces*8+1)*6+6); // 1
943 
944  // Add facets points
945  G4int posInVertice;
946  for (G4int a = 0; a<aNoFaces; a++) {
947  posInVertice = a*4*6;
948  vertices.insert (vertices.end(),fOglVertex.begin()+posInVertice,fOglVertex.begin()+posInVertice+1*6+6); // AB
949  }
950  vertices.insert (vertices.end(),fOglVertex.begin(),fOglVertex.begin()+1*6*6); // AB
951  fOglVertex = vertices;
952 
953  // Add indices for top :
954  // simple version : 0-2-0-4-0-6-0-8-0-10..
955  // optimized version : 2-0-4-6- 6-0-8-10.. but we have to deal with odd faces numbers
956  for (G4int a=0; a<aNoFaces; a++) {
957  fOglIndices.push_back(0);
958  fOglIndices.push_back(a*2+2);
959  }
960  // close strip
961  fOglIndices.push_back(0);
962  fOglIndices.push_back(2);
963 
964  // Add indices for faces
965  for (G4int a = 0; a<aNoFaces; a++) {
966  fOglIndices.push_back(a*2+2);
967  fOglIndices.push_back(a*2+1+2);
968  }
969  fOglIndices.push_back(2);
970  fOglIndices.push_back(2+1);
971 
972  // Second : top
973  // 3-1-5-1-7-1-9-1..
974  for (G4int a=0; a<aNoFaces; a++) {
975  fOglIndices.push_back(a*2+3);
976  fOglIndices.push_back(1);
977  }
978  // close strip
979  fOglIndices.push_back(0+3);
980 
981  fDrawArrayType = GL_TRIANGLE_STRIP;
982  fEmulate_GL_QUADS = false;
983 }
984 
985 void G4OpenGLSceneHandler::glBeginVBO(GLenum type) {
986  fDrawArrayType = type;
987 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
988  glGenBuffers(1,&fVertexBufferObject);
989  glGenBuffers(1,&fIndicesBufferObject);
990 #else
991  fVertexBufferObject = glCreateBuffer(); //glGenBuffer(1,fVertexBufferObject_2)
992  fIndicesBufferObject = glCreateBuffer(); //glGenBuffer(1,fIndicesBufferObject_2)
993 #endif
994 
995  // clear data and indices for OpenGL
996  fOglVertex.clear();
997  fOglIndices.clear();
998 }
999 
1000 // 2 cases :
1001 /*
1002  glDrawArray : if there is no vertex indices : fOglIndices.size() == 0
1003  glDrawElements : if there is vertex indices : fOglIndices.size() != 0
1004 
1005  */
1006 void G4OpenGLSceneHandler::glEndVBO() {
1007  if (fOglIndices.size() == 0) {
1008 
1009 
1010  std::vector<double> vertices;
1011  // check if it is a GL_QUADS emulation
1012  if (fEmulate_GL_QUADS == true) {
1013  fEmulate_GL_QUADS = false;
1014  // A point has 6 double : Vx Vy Vz Nx Ny Nz
1015  // A QUAD should be like this
1016  /*
1017  0 3/4 7/8 ..
1018 
1019  1 2/5 6/9 ..
1020  */
1021  // And if 3==4 and 2==5, we should do it like this for a TRIANGLES_STRIP
1022  /*
1023  0 4 8 ..
1024  | / | / |
1025  1 5 9 ..
1026  // Optimized, 1st level : 24f/15sec with 10 cones
1027  // non Optimized, 1st level : 12f/15sec with 10 cones
1028  */
1029  // should be 4 points
1030  for (unsigned int a=0; a<fOglVertex.size(); a+=6*4) {
1031  vertices.insert (vertices.end(),fOglVertex.begin()+a,fOglVertex.begin()+a+1*6+6); // 0-1
1032  // if 2-3 == 4-5, do not add them
1033  // if differents, we are obliged to create a new GL_TRIANGLE_STRIP
1034  if (a+4*6+5 < fOglVertex.size()) {
1035  if ((fOglVertex[a+2*6+0] != fOglVertex[a+5*6+0]) || //Vx for 2 and 5
1036  (fOglVertex[a+2*6+1] != fOglVertex[a+5*6+1]) || //Vy for 2 and 5
1037  (fOglVertex[a+2*6+2] != fOglVertex[a+5*6+2]) || //Vz for 2 and 5
1038  (fOglVertex[a+2*6+3] != fOglVertex[a+5*6+3]) || //Px for 2 and 5
1039  (fOglVertex[a+2*6+4] != fOglVertex[a+5*6+4]) || //Py for 2 and 5
1040  (fOglVertex[a+2*6+5] != fOglVertex[a+5*6+5]) || //Pz for 2 and 5
1041 
1042  (fOglVertex[a+3*6+0] != fOglVertex[a+4*6+0]) || //Vx for 3 and 4
1043  (fOglVertex[a+3*6+1] != fOglVertex[a+4*6+1]) || //Vy for 3 and 4
1044  (fOglVertex[a+3*6+2] != fOglVertex[a+4*6+2]) || //Vz for 3 and 4
1045  (fOglVertex[a+3*6+3] != fOglVertex[a+4*6+3]) || //Px for 3 and 4
1046  (fOglVertex[a+3*6+4] != fOglVertex[a+4*6+4]) || //Py for 3 and 4
1047  (fOglVertex[a+3*6+5] != fOglVertex[a+4*6+5])) { //Pz for 3 and 4
1048  // add last points
1049  vertices.insert (vertices.end(),fOglVertex.begin()+a+3*6,fOglVertex.begin()+a+3*6+6); // 3
1050  vertices.insert (vertices.end(),fOglVertex.begin()+a+2*6,fOglVertex.begin()+a+2*6+6); // 2
1051  // build and send the GL_TRIANGLE_STRIP
1052  drawVBOArray(vertices);
1053  vertices.clear();
1054  }
1055  } else { // end of volume
1056  vertices.insert (vertices.end(),fOglVertex.begin()+a+3*6,fOglVertex.begin()+a+3*6+6); // 3
1057  vertices.insert (vertices.end(),fOglVertex.begin()+a+2*6,fOglVertex.begin()+a+2*6+6); // 2
1058  }
1059  }
1060  fOglVertex = vertices;
1061  }
1062 
1063  drawVBOArray(fOglVertex);
1064 
1065  } else {
1066 
1067  // Bind VBO
1068  glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject);
1069 
1070  // Load fOglVertex into VBO
1071 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1072  int sizeV = fOglVertex.size();
1073  // FIXME : perhaps a problem withBufferData in OpenGL other than WebGL ?
1074 // void glBufferData( GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
1075  glBufferData(GL_ARRAY_BUFFER, sizeof(double)*sizeV, &fOglVertex[0], GL_STATIC_DRAW);
1076 #else
1077  glBufferDatafv(GL_ARRAY_BUFFER, fOglVertex.begin(), fOglVertex.end(), GL_STATIC_DRAW);
1078 #endif
1079 
1080  // Bind IBO
1081  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fIndicesBufferObject);
1082 
1083  // Load fOglVertex into VBO
1084 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1085  int sizeI = fOglIndices.size();
1086  glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(int)*sizeI, &fOglIndices[0], GL_STATIC_DRAW);
1087 #else
1088  glBufferDataiv(GL_ELEMENT_ARRAY_BUFFER, fOglIndices.begin(), fOglIndices.end(), GL_STATIC_DRAW, GL_UNSIGNED_BYTE);
1089 #endif
1090 
1091  //----------------------------
1092  // Draw VBO
1093  //----------------------------
1094  glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject);
1095  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fIndicesBufferObject);
1096 
1097  // the fVertexPositionAttribute is inside the G4OpenGLViewer
1098  G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
1099  if (pGLViewer) {
1100  glEnableVertexAttribArray(pGLViewer->fVertexPositionAttribute);
1101 
1102  glVertexAttribPointer(pGLViewer->fVertexPositionAttribute,
1103  3, // size: Every vertex has an X, Y anc Z component
1104  GL_FLOAT, // type: They are floats
1105  GL_FALSE, // normalized: Please, do NOT normalize the vertices
1106  2*3*4, // stride: The first byte of the next vertex is located this
1107  // amount of bytes further. The format of the VBO is
1108  // vx, vy, vz, nx, ny, nz and every element is a
1109  // Float32, hence 4 bytes large
1110  0); // offset: The byte position of the first vertex in the buffer
1111  }
1112 
1113 
1114  glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject);
1115  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fIndicesBufferObject);
1116 // glDrawElements(fDrawArrayType, fOglIndices.size(), GL_UNSIGNED_SHORT, 0);
1117  glDrawElements(fDrawArrayType, fOglIndices.size(), GL_UNSIGNED_SHORT, 0);
1118 
1119  if (pGLViewer) {
1120  glDisableVertexAttribArray(pGLViewer->fVertexPositionAttribute);
1121  }
1122 
1123  // delete the buffer
1124 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1125  glDeleteBuffers(1,&fVertexBufferObject);
1126 #else
1127  glDeleteBuffer(fVertexBufferObject);
1128 #endif
1129  }
1130 }
1131 
1132 void G4OpenGLSceneHandler::drawVBOArray(std::vector<double> vertices) {
1133 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1134  glGenBuffers(1,&fVertexBufferObject);
1135  glGenBuffers(1,&fIndicesBufferObject);
1136 #else
1137  fVertexBufferObject = glCreateBuffer(); //glGenBuffer(1,fVertexBufferObject_2)
1138  fIndicesBufferObject = glCreateBuffer(); //glGenBuffer(1,fIndicesBufferObject_2)
1139 #endif
1140 
1141  // Bind this buffer
1142  glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject);
1143  // Load oglData into VBO
1144 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1145  int s = vertices.size();
1146  glBufferData(GL_ARRAY_BUFFER, sizeof(double)*s, &vertices[0], GL_STATIC_DRAW);
1147 #else
1148  glBufferDatafv(GL_ARRAY_BUFFER, vertices.begin(), vertices.end(), GL_STATIC_DRAW);
1149 #endif
1150 
1151  //----------------------------
1152  // Draw VBO
1153  //----------------------------
1154  glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject);
1155 
1156  // the fVertexPositionAttribute is inside the G4OpenGLViewer
1157  G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
1158  if (pGLViewer) {
1159  glEnableVertexAttribArray(pGLViewer->fVertexPositionAttribute);
1160 
1161 // glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer)
1162 
1163 /*
1164  GL_DOUBLE
1165  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.
1166 
1167  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.
1168  */
1169 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1170  glVertexAttribPointer(pGLViewer->fVertexPositionAttribute,
1171  3, // size: Every vertex has an X, Y anc Z component
1172  GL_DOUBLE, // type: They are double
1173  GL_FALSE, // normalized: Please, do NOT normalize the vertices
1174  6*sizeof(double), // stride: The first byte of the next vertex is located this
1175  // amount of bytes further. The format of the VBO is
1176  // vx, vy, vz, nx, ny, nz and every element is a
1177  // Float32, hence 4 bytes large
1178  0); // offset: The byte position of the first vertex in the buffer
1179 #else
1180  glVertexAttribPointer(pGLViewer->fVertexPositionAttribute,
1181  3, // size: Every vertex has an X, Y anc Z component
1182  GL_FLOAT, // type: They are floats
1183  GL_FALSE, // normalized: Please, do NOT normalize the vertices
1184  2*3*4, // stride: The first byte of the next vertex is located this
1185  // amount of bytes further. The format of the VBO is
1186  // vx, vy, vz, nx, ny, nz and every element is a
1187  // Float32, hence 4 bytes large
1188  0); // offset: The byte position of the first vertex in the buffer
1189 #endif
1190  }
1191 
1192  glDrawArrays(fDrawArrayType, // GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP, and GL_TRIANGLES
1193  0, vertices.size()/6);
1194  if (pGLViewer) {
1195 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1196  glDisableClientState( GL_VERTEX_ARRAY );
1197 #else
1198  glDisableVertexAttribArray(pGLViewer->fVertexPositionAttribute);
1199 #endif
1200  }
1201 
1202  // delet the buffer
1203 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER
1204  glDeleteBuffers(1,&fVertexBufferObject);
1205 #else
1206  glDeleteBuffer(fVertexBufferObject);
1207 #endif
1208 }
1209 #endif
1210 
1211 
1212 #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
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:168
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
static const double twopi
Definition: G4SIunits.hh:75
virtual void EndPrimitives()
HepGeom::Transform3D G4Transform3D
virtual void BeginPrimitives2D(const G4Transform3D &objectTransformation)
virtual void AddCompound(const G4VTrajectory &)
static const double pi
Definition: G4SIunits.hh:74
virtual void ProcessScene()
const G4double x[NPOINTSGL]
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