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