Geant4 11.4.0
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
96
101
103{
104 std::map<GLuint, G4AttHolder*>::iterator i;
105 for (i = fPickMap.begin(); i != fPickMap.end(); ++i) delete i->second;
106 fPickMap.clear();
107}
108
112
114{
116
117 // Drawing transients, e.g., trajectories.
118
119 if (!fpScene) {
120 // No scene - shouldn't happen
121 glFlush();
122 return;
123 }
124 // Get event from modeling parameters
125 if (!fpModel) {
126 // No model - shouldn't happen
127 glFlush();
128 return;
129 }
130 const G4ModelingParameters* modelingParameters =
131 fpModel->GetModelingParameters();
132 if (!modelingParameters) {
133 // No modeling parameters - shouldn't happen
134 glFlush();
135 return;
136 }
137 const G4Event* thisEvent = modelingParameters->GetEvent();
138 if (!thisEvent) {
139 // No event, so not in event loop.
140 if (fFlushAction == endOfEvent) {
142 } else if (fFlushAction == NthEvent) {
144 }
145 }
147 if (!runMan) {
148 // No run manager - shouldn't happen
149 glFlush();
150 return;
151 }
152 const G4Run* thisRun = runMan->GetCurrentRun();
153 if (!thisRun) {
154 // No run, so not in event loop.
155 if (fFlushAction == endOfRun) {
157 } else if (fFlushAction == NthEvent) {
159 }
160 }
161
162 switch (fFlushAction) {
163 case endOfEvent:
164 // If "/vis/scene/endOfEventAction refresh", primitives are flushed at
165 // end of run anyway, so only scale if false.
166 if (!fpScene->GetRefreshAtEndOfEvent()) {
167 // But if "/vis/scene/endOfEventAction accumulate", ShowView is not
168 // called until end of run, so we have to watch for a new event.
169 // Get event from modeling parameters
170 G4int thisEventID = thisEvent->GetEventID();
171 static G4int lastEventID = 0;
172 if (thisEventID != lastEventID) {
173 glFlush();
174 lastEventID = thisEventID;
175 }
176 }
177 break;
178 case endOfRun:
179 // If "/vis/scene/endOfRunAction refresh", primitives are flushed at
180 // end of run anyway, so only scale if false.
181 if (!fpScene->GetRefreshAtEndOfRun()) {
182 // If "/vis/scene/endOfRunAction accumulate", ShowView is never called
183 // so we have to watch for a new run.
184 G4int thisRunID = thisRun->GetRunID();
185 static G4int lastRunID = 0;
186 if (thisRunID != lastRunID) {
187 glFlush();
188 lastRunID = thisRunID;
189 }
190 }
191 break;
192 case eachPrimitive:
193 // This is equivalent to numeric with fEntitiesFlushInterval == 1.
195 [[fallthrough]]; // Fall through to NthPrimitive.
196 case NthPrimitive:
197 { // Encapsulate in scope {} brackets to satisfy Windows.
198 static G4int primitivesWaitingToBeFlushed = 0;
199 primitivesWaitingToBeFlushed++;
200 if (primitivesWaitingToBeFlushed < fEntitiesFlushInterval) return;
201 glFlush();
202 primitivesWaitingToBeFlushed = 0;
203 break;
204 }
205 case NthEvent:
206 // If "/vis/scene/endOfEventAction refresh", primitives are flushed at
207 // end of event anyway, so only scale if false.
208 if (!fpScene->GetRefreshAtEndOfEvent()) {
209 G4int thisEventID = thisEvent->GetEventID();
210 static G4int lastEventID = 0;
211 if (thisEventID != lastEventID) {
212 static G4int eventsWaitingToBeFlushed = 0;
213 eventsWaitingToBeFlushed++;
214 if (eventsWaitingToBeFlushed < fEntitiesFlushInterval) return;
215 glFlush();
216 eventsWaitingToBeFlushed = 0;
217 lastEventID = thisEventID;
218 }
219 }
220 break;
221 case never:
222 break;
223 default:
224 break;
225 }
226
227 }
228
229 else
230
231 {
232
233 // For run duration model drawing (detector drawing):
234 // Immediate mode: a huge speed up is obtained if flushes are scaled.
235 // Stored mode: no discernable difference since drawing is done to the
236 // back buffer and then swapped.
237 // So eachPrimitive and NthPrimitive make sense. But endOfEvent and
238 // endOfRun are treated as "no action", i.e., a flush will only be issued,
239 // as happens anyway, when drawing is complete.
240
241 switch (fFlushAction) {
242 case endOfEvent:
243 break;
244 case endOfRun:
245 break;
246 case eachPrimitive:
247 // This is equivalent to NthPrimitive with fEntitiesFlushInterval == 1.
249 [[fallthrough]]; // Fall through to NthPrimitive.
250 case NthPrimitive:
251 { // Encapsulate in scope {} brackets to satisfy Windows.
252 static G4int primitivesWaitingToBeFlushed = 0;
253 primitivesWaitingToBeFlushed++;
254 if (primitivesWaitingToBeFlushed < fEntitiesFlushInterval) return;
255 glFlush();
256 primitivesWaitingToBeFlushed = 0;
257 break;
258 }
259 case NthEvent:
260 break;
261 case never:
262 break;
263 default:
264 break;
265 }
266
267 }
268}
269
294
296(const G4Transform3D& objectTransformation,
297 const G4VisAttributes& visAttribs)
298{
299 G4VSceneHandler::PreAddSolid (objectTransformation, visAttribs);
300}
301
303(const G4Transform3D& objectTransformation)
304{
305 glClearColor (0.0, 0.0, 0.0, 0.0);
306 glClearDepth (1.0);
307 glDisable (GL_LINE_SMOOTH);
308 glDisable (GL_POLYGON_SMOOTH);
309 glDisable (GL_POINT_SMOOTH);
310
311 G4VSceneHandler::BeginPrimitives (objectTransformation);
312}
313
318
320(const G4Transform3D& objectTransformation)
321{
322 glClearColor (0.0, 0.0, 0.0, 0.0);
323 glClearDepth (1.0);
324 glDisable (GL_LINE_SMOOTH);
325 glDisable (GL_POLYGON_SMOOTH);
326 glDisable (GL_POINT_SMOOTH);
327
328 G4VSceneHandler::BeginPrimitives2D (objectTransformation);
329}
330
335
337{
339 // If clipping done in G4OpenGLViewer::SetView
340 // return 0;
341 // Note: if you change this, you must also change
342 // G4OpenGLStoredViewer::CompareForKernelVisit
343}
344
346{
347 // return G4VSceneHandler::CreateCutawaySolid();
348 // If cutaway done in G4OpenGLViewer::SetView.
349 return 0;
350 // Note: if you change this, you must also change
351 // G4OpenGLStoredViewer::CompareForKernelVisit
352}
353
355{
356 std::size_t nPoints = line.size ();
357 if (nPoints <= 0) return;
358
359 // Note: colour and depth test treated in sub-class.
360
361 glDisable (GL_LIGHTING);
362
364 // Need access to method in G4OpenGLViewer. static_cast doesn't
365 // work with a virtual base class, so use dynamic_cast. No need to
366 // test the outcome since viewer is guaranteed to be a
367 // G4OpenGLViewer, but test it anyway to keep Coverity happy.
368 G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
369 if (pGLViewer) pGLViewer->ChangeLineWidth(lineWidth);
370
371 fEdgeFlag = true;
372 glBegin (GL_LINE_STRIP);
373 // No ned glEdgeFlag for lines :
374 // Boundary and nonboundary edge flags on vertices are significant only if GL_POLYGON_MODE is set to GL_POINT or GL_LINE. See glPolygonMode.
375
376 // glEdgeFlag (GL_TRUE);
377 for (std::size_t iPoint = 0; iPoint < nPoints; ++iPoint) {
378 G4double x, y, z;
379 x = line[iPoint].x();
380 y = line[iPoint].y();
381 z = line[iPoint].z();
382 glVertex3d (x, y, z);
383 }
384 glEnd ();
385}
386
388{
389 if (polymarker.size() == 0) {
390 return;
391 }
392
393 // Note: colour and depth test treated in sub-class.
394
395 glDisable (GL_LIGHTING);
396
397 MarkerSizeType sizeType;
398 G4double size = GetMarkerSize(polymarker, sizeType);
399
400 // Need access to method in G4OpenGLViewer. static_cast doesn't
401 // work with a virtual base class, so use dynamic_cast. No need to
402 // test the outcome since viewer is guaranteed to be a
403 // G4OpenGLViewer, but test it anyway to keep Coverity happy.
404 G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
405 if (!pGLViewer) return;
406
407 if (sizeType == world) { // Size specified in world coordinates.
409 pGLViewer->ChangeLineWidth(lineWidth);
410
411 G4VMarker::FillStyle style = polymarker.GetFillStyle();
412
413 // G4bool filled = false; Not actually used - comment out to prevent compiler warnings (JA).
414 static G4bool hashedWarned = false;
415
416 switch (style) {
418 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
419 glEdgeFlag (GL_TRUE);
420 //filled = false;
421 break;
423 if (!hashedWarned) {
424 G4cout << "Hashed fill style in G4OpenGLSceneHandler."
425 << "\n Not implemented. Using G4VMarker::filled."
426 << G4endl;
427 hashedWarned = true;
428 }
429 // Maybe use
430 //glPolygonStipple (fStippleMaskHashed);
431 [[fallthrough]]; // Drop through to filled...
433 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
434 //filled = true;
435 break;
436 }
437 }
438
439 // Draw...
440 if (sizeType == world) { // Size specified in world coordinates.
441
442 G4int nSides;
443 G4double startPhi;
444 switch (polymarker.GetMarkerType()) {
445 default:
447 [[fallthrough]]; // Fall through to circles
449 nSides = GetNoOfSides(fpVisAttribs);
450 startPhi = 0.;
451 break;
453 nSides = 4;
454 startPhi = -pi / 4.;
455 break;
456 }
457
458 const G4Vector3D& viewpointDirection =
459 fpViewer -> GetViewParameters().GetViewpointDirection();
460 const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector();
461 const G4double dPhi = twopi / nSides;
462 const G4double radius = size / 2.;
463 G4Vector3D start = radius * (up.cross(viewpointDirection)).unit();
464 G4double phi;
465 G4int i;
466 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
467 fEdgeFlag = true;
468 glBegin (GL_POLYGON);
469 for (i = 0, phi = startPhi; i < nSides; i++, phi += dPhi) {
470 G4Vector3D r = start; r.rotate(phi, viewpointDirection);
471 G4Vector3D p = polymarker[iPoint] + r;
472 glVertex3d (p.x(), p.y(), p.z());
473 }
474 glEnd ();
475 }
476
477 } else { // Size specified in screen (window) coordinates.
478
479 pGLViewer->ChangePointSize(size);
480
481 switch (polymarker.GetMarkerType()) {
482 default:
484 [[fallthrough]]; // Fall through to circles
486 if (fpViewer->GetViewParameters().IsDotsSmooth()) {
487 glEnable (GL_POINT_SMOOTH);
488 }
489 break;
491 break;
492 }
493 glBegin (GL_POINTS);
494 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
495 G4Point3D centre = polymarker[iPoint];
496 glVertex3d(centre.x(),centre.y(),centre.z());
497 }
498 glEnd();
499 }
500}
501
503 // Pass to specific viewer via virtual function DrawText.
504 G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
505 if (pGLViewer) pGLViewer->DrawText(text);
506}
507
509 G4Polymarker oneCircle(circle);
510 oneCircle.push_back(circle.GetPosition());
512 // Call this AddPrimitive to avoid re-doing sub-class code.
514}
515
517 G4Polymarker oneSquare(square);
518 oneSquare.push_back(square.GetPosition());
520 // Call this AddPrimitive to avoid re-doing sub-class code.
522}
523
524//Method for handling G4Polyhedron objects for drawing solids.
526
527 // Assume all facets are planar convex quadrilaterals.
528 // Draw each facet individually
529
530 if (polyhedron.GetNoFacets() == 0) return;
531
532 // Need access to data in G4OpenGLViewer. static_cast doesn't work
533 // with a virtual base class, so use dynamic_cast.
534 G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
535 if (!pGLViewer) return;
536
537 // Get view parameters that the user can force through the vis
538 // attributes, thereby over-riding the current view parameter.
540
541 // Note that in stored mode, because this call gets embedded in a display
542 // list, it is the colour _at the time of_ creation of the display list, so
543 // even if the colour is changed, for example, by interaction with a Qt
544 // window, current_colour does not change.
545 GLfloat* painting_colour;
546 GLfloat clear_colour[4];
547 GLfloat current_colour[4];
548 glGetFloatv (GL_CURRENT_COLOR, current_colour);
549
550 G4bool isTransparent = false;
551 if (current_colour[3] < 1.) { // This object is transparent
552 isTransparent = true;
553 }
554
555 if (drawing_style == G4ViewParameters::hlr) {
556 // This is the colour used to paint surfaces in hlr mode.
557 glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour);
558 painting_colour = clear_colour;
559 } else { // drawing_style == G4ViewParameters::hlhsr
560 painting_colour = current_colour;
561 }
562
564 pGLViewer->ChangeLineWidth(lineWidth);
565
566 G4bool isAuxEdgeVisible = GetAuxEdgeVisible (fpVisAttribs);
567
568 G4bool clipping = pGLViewer->fVP.IsSection() || pGLViewer->fVP.IsCutaway();
569
570 // Lighting disabled unless otherwise requested
571 glDisable (GL_LIGHTING);
572
573 switch (drawing_style) {
575 // Set up as for hidden line removal but paint polygon faces later...
577 glEnable (GL_STENCIL_TEST);
578 // The stencil buffer is cleared in G4OpenGLViewer::ClearView.
579 // The procedure below leaves it clear.
580 glStencilFunc (GL_ALWAYS, 0, 1);
581 glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
582 glEnable (GL_DEPTH_TEST);
583 glDepthFunc (GL_LEQUAL);
584 if (isTransparent) {
585 // Transparent...
586 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
587 glEnable(GL_COLOR_MATERIAL);
588 //glDisable (GL_CULL_FACE);
589 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
590 } else {
591 // Opaque...
592 if (clipping) {
593 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
594 glEnable(GL_COLOR_MATERIAL);
595 //glDisable (GL_CULL_FACE);
596 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
597 } else {
598 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
599 glEnable(GL_COLOR_MATERIAL);
600 //glEnable (GL_CULL_FACE);
601 //glCullFace (GL_BACK);
602 glPolygonMode (GL_FRONT, GL_LINE);
603 }
604 }
605 break;
607 glEnable (GL_DEPTH_TEST);
608 glDepthFunc (GL_LEQUAL);
609 if (isTransparent) {
610 // Transparent...
611 glDepthMask (GL_FALSE); // Make depth buffer read-only.
612 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
613 glEnable(GL_COLOR_MATERIAL);
614 //glDisable (GL_CULL_FACE);
615 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
616 } else {
617 // Opaque...
618 glDepthMask (GL_TRUE); // Make depth buffer writable (default).
619 if (clipping) {
620 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
621 glEnable(GL_COLOR_MATERIAL);
622 //glDisable (GL_CULL_FACE);
623 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
624 } else {
625 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
626 glEnable(GL_COLOR_MATERIAL);
627 //glEnable (GL_CULL_FACE);
628 //glCullFace (GL_BACK);
629 glPolygonMode (GL_FRONT, GL_FILL);
630 }
631 }
632 if (!fProcessing2D) glEnable (GL_LIGHTING);
633 break;
635 default:
636 glEnable (GL_DEPTH_TEST);
637 glDepthFunc (GL_LEQUAL); //??? was GL_ALWAYS
638 //glDisable (GL_CULL_FACE);
639 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
640 break;
641 }
642
643 //Loop through all the facets...
644 fEdgeFlag = true;
645 glBegin (GL_QUADS);
646 glEdgeFlag (GL_TRUE);
647 G4bool notLastFace;
648 do {
649
650 //First, find vertices, edgeflags and normals and note "not last facet"...
651 G4Point3D vertex[4];
652 G4int edgeFlag[4];
653 G4Normal3D normals[4];
654 G4int nEdges;
655 notLastFace = polyhedron.GetNextFacet(nEdges, vertex, edgeFlag, normals);
656
657 //Loop through the four edges of each G4Facet...
658 for(G4int edgeCount = 0; edgeCount < nEdges; ++edgeCount) {
659 // Check to see if edge is visible or not...
660 if (isAuxEdgeVisible) {
661 edgeFlag[edgeCount] = 1;
662 }
663 if (edgeFlag[edgeCount] > 0) {
664 if (fEdgeFlag != true) {
665 glEdgeFlag (GL_TRUE);
666 fEdgeFlag = true;
667 }
668 } else {
669 if (fEdgeFlag != false) {
670 glEdgeFlag (GL_FALSE);
671 fEdgeFlag = false;
672 }
673 }
674 glNormal3d (normals[edgeCount].x(),
675 normals[edgeCount].y(),
676 normals[edgeCount].z());
677 glVertex3d (vertex[edgeCount].x(),
678 vertex[edgeCount].y(),
679 vertex[edgeCount].z());
680 }
681
682 // HepPolyhedron produces triangles too; in that case add an extra
683 // vertex identical to first...
684 if (nEdges == 3) {
685 G4int edgeCount = 3;
686 normals[edgeCount] = normals[0];
687 vertex[edgeCount] = vertex[0];
688 edgeFlag[edgeCount] = -1;
689 if (fEdgeFlag != false) {
690 glEdgeFlag (GL_FALSE);
691 fEdgeFlag = false;
692 }
693
694 glNormal3d (normals[edgeCount].x(),
695 normals[edgeCount].y(),
696 normals[edgeCount].z());
697 glVertex3d (vertex[edgeCount].x(),
698 vertex[edgeCount].y(),
699 vertex[edgeCount].z());
700 }
701 // Trap situation where number of edges is > 4...
702 if (nEdges > 4) {
703 G4cerr <<
704 "G4OpenGLSceneHandler::AddPrimitive(G4Polyhedron): WARNING"
705 "\n G4Polyhedron facet with " << nEdges << " edges" << G4endl;
706 }
707
708
709 // Do it all over again (twice) for hlr...
710 if (drawing_style == G4ViewParameters::hlr ||
711 drawing_style == G4ViewParameters::hlhsr) {
712
713 glDisable(GL_COLOR_MATERIAL); // Revert to glMaterial for hlr/sr.
714 glEnd (); // Placed here to balance glBegin above, allowing GL
715
716 // state changes below, then glBegin again. Avoids
717 // having glBegin/End pairs *inside* loop in the more
718 // usual case of no hidden line removal.
719
720 // Lighting disabled unless otherwise requested
721 glDisable (GL_LIGHTING);
722
723 // Draw through stencil...
724 glStencilFunc (GL_EQUAL, 0, 1);
725 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
726 if (drawing_style == G4ViewParameters::hlhsr) {
727 if (!fProcessing2D) glEnable (GL_LIGHTING);
728 }
729 glEnable (GL_DEPTH_TEST);
730 glDepthFunc (GL_LEQUAL);
731 if (isTransparent) {
732 // Transparent...
733 glDepthMask (GL_FALSE); // Make depth buffer read-only.
734 //glDisable (GL_CULL_FACE);
735 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
736 } else {
737 // Opaque...
738 glDepthMask (GL_TRUE); // Make depth buffer writable (default).
739 if (clipping) {
740 //glDisable (GL_CULL_FACE);
741 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
742 } else {
743 //glEnable (GL_CULL_FACE);
744 //glCullFace (GL_BACK);
745 glPolygonMode (GL_FRONT, GL_FILL);
746 }
747 }
748 if (drawing_style == G4ViewParameters::hlr) {
749 if (isTransparent) {
750 // Transparent - don't paint...
751 goto end_of_drawing_through_stencil;
752 }
753 }
754 if (isTransparent) {
755 // Transparent...
756 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, painting_colour);
757 } else {
758 // Opaque...
759 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, painting_colour);
760 }
761 glColor4fv (painting_colour);
762 glBegin (GL_QUADS);
763 glEdgeFlag (GL_TRUE);
764 fEdgeFlag = true;
765
766 for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
767 if (edgeFlag[edgeCount] > 0) {
768 if (fEdgeFlag != true) {
769 glEdgeFlag (GL_TRUE);
770 fEdgeFlag = true;
771 }
772 } else {
773 if (fEdgeFlag != false) {
774 glEdgeFlag (GL_FALSE);
775 fEdgeFlag = false;
776 }
777 }
778 glNormal3d (normals[edgeCount].x(),
779 normals[edgeCount].y(),
780 normals[edgeCount].z());
781 glVertex3d (vertex[edgeCount].x(),
782 vertex[edgeCount].y(),
783 vertex[edgeCount].z());
784 }
785 glEnd ();
786 end_of_drawing_through_stencil:
787
788 // and once more to reset the stencil bits...
789 glStencilFunc (GL_ALWAYS, 0, 1);
790 glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
791 glDepthFunc (GL_LEQUAL); // to make sure line gets drawn.
792 if (isTransparent) {
793 // Transparent...
794 //glDisable (GL_CULL_FACE);
795 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
796 } else {
797 // Opaque...
798 if (clipping) {
799 //glDisable (GL_CULL_FACE);
800 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
801 } else {
802 //glEnable (GL_CULL_FACE);
803 //glCullFace (GL_BACK);
804 glPolygonMode (GL_FRONT, GL_LINE);
805 }
806 }
807 glDisable (GL_LIGHTING);
808 glColor4fv (current_colour);
809 fEdgeFlag = true;
810 glBegin (GL_QUADS);
811 glEdgeFlag (GL_TRUE);
812 fEdgeFlag = true;
813 for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
814 if (edgeFlag[edgeCount] > 0) {
815 if (fEdgeFlag != true) {
816 glEdgeFlag (GL_TRUE);
817 fEdgeFlag = true;
818 }
819 } else {
820 if (fEdgeFlag != false) {
821 glEdgeFlag (GL_FALSE);
822 fEdgeFlag = false;
823 }
824 }
825 glNormal3d (normals[edgeCount].x(),
826 normals[edgeCount].y(),
827 normals[edgeCount].z());
828 glVertex3d (vertex[edgeCount].x(),
829 vertex[edgeCount].y(),
830 vertex[edgeCount].z());
831 }
832 glEnd ();
833
834 glDepthFunc (GL_LEQUAL); // Revert for next facet.
835 fEdgeFlag = true;
836 glBegin (GL_QUADS); // Ready for next facet. GL
837 glEdgeFlag (GL_TRUE);
838 fEdgeFlag = true;
839 // says it ignores incomplete
840 // quadrilaterals, so final empty
841 // glBegin/End sequence should be OK.
842 }
843 } while (notLastFace);
844
845 glEnd ();
846 glDisable (GL_STENCIL_TEST); // Revert to default for next primitive.
847 glDepthMask (GL_TRUE); // Revert to default for next primitive.
848 glDisable (GL_LIGHTING); // Revert to default for next primitive.
849}
850
854
856 G4VSceneHandler::AddCompound(hit); // For now.
857}
858
860 G4VSceneHandler::AddCompound(digi); // For now.
861}
862
866
870
HepGeom::Normal3D< G4double > G4Normal3D
Definition G4Normal3D.hh:34
HepGeom::Point3D< G4double > G4Point3D
Definition G4Point3D.hh:34
HepGeom::Transform3D G4Transform3D
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
HepGeom::Vector3D< G4double > G4Vector3D
Definition G4Vector3D.hh:34
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
G4DisplacedSolid is a solid that has been shifted from its original frame of reference to a new one....
G4int GetEventID() const
Definition G4Event.hh:126
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:48
G4int GetRunID() const
Definition G4Run.hh:82
FillStyle GetFillStyle() const
G4Point3D GetPosition() 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 &)
G4VSceneHandler(G4VGraphicsSystem &system, G4int id, const G4String &name="")
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 &)
G4ViewParameters fVP
Definition G4VViewer.hh:272
G4bool IsCutaway() const
G4bool IsSection() 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