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