Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4OpenGLStoredSceneHandler.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 10th February 1997
30// OpenGL stored scene - creates OpenGL display lists.
31
33
36#include "G4VPhysicalVolume.hh"
37#include "G4LogicalVolume.hh"
38#include "G4Polyline.hh"
39#include "G4Polymarker.hh"
40#include "G4Text.hh"
41#include "G4Circle.hh"
42#include "G4Square.hh"
43#include "G4Polyhedron.hh"
44#include "G4AttHolder.hh"
46#include "G4OpenGLViewer.hh"
47#include "G4AttHolder.hh"
48
49#include <typeinfo>
50
52
54
56 fDisplayListId(0),
57 fPickName(0),
58 fpG4TextPlus(0),
59 fMarkerOrPolyline(false)
60{}
61
64 fTransform(po.fTransform),
66 fColour(po.fColour),
67 fpG4TextPlus(po.fpG4TextPlus? new G4TextPlus(*po.fpG4TextPlus): 0),
68 fMarkerOrPolyline(po.fMarkerOrPolyline)
69{}
70
73 fTransform(tr),
74 fPickName(0),
75 fpG4TextPlus(0),
76 fMarkerOrPolyline(false)
77{}
78
80{
81 delete fpG4TextPlus;
82}
83
84G4OpenGLStoredSceneHandler::PO& G4OpenGLStoredSceneHandler::PO::operator=
86{
87 if (&rhs == this) return *this;
88 fDisplayListId = rhs.fDisplayListId;
89 fTransform = rhs.fTransform;
90 fPickName = rhs.fPickName;
91 fColour = rhs.fColour;
92 fpG4TextPlus = rhs.fpG4TextPlus? new G4TextPlus(*rhs.fpG4TextPlus): 0;
93 fMarkerOrPolyline = rhs.fMarkerOrPolyline;
94 return *this;
95}
96
99 fPickName(0),
100 fStartTime(-G4VisAttributes::fVeryLongTime),
101 fEndTime(G4VisAttributes::fVeryLongTime),
102 fpG4TextPlus(0),
103 fMarkerOrPolyline(false)
104{}
105
108 fTransform(to.fTransform),
110 fStartTime(to.fStartTime),
111 fEndTime(to.fEndTime),
112 fColour(to.fColour),
113 fpG4TextPlus(to.fpG4TextPlus? new G4TextPlus(*to.fpG4TextPlus): 0),
114 fMarkerOrPolyline(to.fMarkerOrPolyline)
115{}
116
118 fDisplayListId(id),
119 fTransform(tr),
120 fPickName(0),
121 fStartTime(-G4VisAttributes::fVeryLongTime),
122 fEndTime(G4VisAttributes::fVeryLongTime),
123 fpG4TextPlus(0),
124 fMarkerOrPolyline(false)
125{}
126
128{
129 delete fpG4TextPlus;
130}
131
132G4OpenGLStoredSceneHandler::TO& G4OpenGLStoredSceneHandler::TO::operator=
134{
135 if (&rhs == this) return *this;
136 fDisplayListId = rhs.fDisplayListId;
137 fTransform = rhs.fTransform;
138 fPickName = rhs.fPickName;
139 fStartTime = rhs.fStartTime;
140 fEndTime = rhs.fEndTime;
141 fColour = rhs.fColour;
142 fpG4TextPlus = rhs.fpG4TextPlus? new G4TextPlus(*rhs.fpG4TextPlus): 0;
143 fMarkerOrPolyline = rhs.fMarkerOrPolyline;
144 return *this;
145}
146
148(G4VGraphicsSystem& system,
149 const G4String& name):
150G4OpenGLSceneHandler (system, fSceneIdCount++, name),
152fTopPODL (0)
153{}
154
156{}
157
159(const G4Transform3D& objectTransformation)
160{
161 G4OpenGLSceneHandler::BeginPrimitives (objectTransformation);
162 if (fReadyForTransients) glDrawBuffer (GL_FRONT);
163 // Display list setup moved to AddPrimitivePreamble. See notes there.
164}
165
167{
168 // See all primitives immediately... At least soon...
169 ScaledFlush();
170 glDrawBuffer (GL_BACK);
172}
173
175(const G4Transform3D& objectTransformation)
176{
177 G4OpenGLSceneHandler::BeginPrimitives2D(objectTransformation);
178 if (fReadyForTransients) glDrawBuffer (GL_FRONT);
179}
180
182{
183 // See all primitives immediately... At least soon...
184 ScaledFlush();
185 glDrawBuffer (GL_BACK);
187}
188
190{
191 return AddPrimitivePreambleInternal(visible, true, false);
192}
194{
195 return AddPrimitivePreambleInternal(visible, false, true);
196}
198{
199 return AddPrimitivePreambleInternal(visible, false, false);
200}
201
202G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreambleInternal
203(const G4Visible& visible, bool isMarker, bool isPolyline)
204{
205// Get applicable vis attributes for all primitives.
207 const G4Colour& c = GetColour ();
208 G4double opacity = c.GetAlpha ();
209
210 G4bool transparency_enabled = true;
211 G4bool isMarkerNotHidden = true;
212 G4OpenGLViewer* pOGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
213 if (pOGLViewer) {
214 transparency_enabled = pOGLViewer->transparency_enabled;
215 isMarkerNotHidden = pOGLViewer->fVP.IsMarkerNotHidden();
216 }
217
218 G4bool isTransparent = opacity < 1.;
219 G4bool isMarkerOrPolyline = isMarker || isPolyline;
220 G4bool treatAsTransparent = transparency_enabled && isTransparent;
221 G4bool treatAsNotHidden = isMarkerNotHidden && isMarkerOrPolyline;
222
223 if (fProcessing2D) glDisable (GL_DEPTH_TEST);
224 else {
225 if (isMarkerOrPolyline && isMarkerNotHidden)
226 glDisable (GL_DEPTH_TEST);
227 else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);}
228 }
229
230 if (fThreePassCapable) {
231
232 // Ensure transparent objects are drawn *after* opaque ones and before
233 // non-hidden markers. The problem of blending/transparency/alpha
234 // is quite a tricky one - see History of opengl-V07-01-01/2/3.
236 // First pass...
237 if (treatAsTransparent) { // Request pass for transparent objects...
239 }
240 if (treatAsNotHidden) { // Request pass for non-hidden markers...
242 }
243 // On first pass, transparent objects and non-hidden markers are not drawn...
244 if (treatAsTransparent || treatAsNotHidden) {
245 return false; // No further processing.
246 }
247 }
248
249 // On second pass, only transparent objects are drawn...
251 if (!treatAsTransparent) {
252 return false; // No further processing.
253 }
254 }
255
256 // On third pass, only non-hidden markers are drawn...
258 if (!treatAsNotHidden) {
259 return false; // No further processing.
260 }
261 }
262 } // fThreePassCapable
263
264 // Loads G4Atts for picking...
265 G4bool isPicking = false;
267 isPicking = true;
268 glLoadName(++fPickName);
269 G4AttHolder* holder = new G4AttHolder;
270 LoadAtts(visible, holder);
271 fPickMap[fPickName] = holder;
272 }
273
274 // Because of our need to control colour of transients (display by
275 // time fading), display lists may only cover a single primitive.
276 // So display list setup is here.
277
279
280 glPushMatrix();
282 glMultMatrixd (oglt.GetGLMatrix ());
283 if (transparency_enabled) {
284 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
285 } else {
286 glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
287 }
288
289 } else {
290
291 fDisplayListId = glGenLists (1);
292 if (glGetError() == GL_OUT_OF_MEMORY) {
293 static G4int errorCount = 0;
294 if (errorCount < 5) {
295 errorCount++;
297 ed <<
298 "Error attempting to create an OpenGL display list."
299 "\nCurrent display list id: " << fDisplayListId <<
300 "\nMaybe out of memory?";
302 ("G4OpenGLStoredSceneHandler::AddPrimitivePreambleInternal","opengl1001",
303 JustWarning,ed);
304 }
305 return false;
306 }
309 if (isPicking) to.fPickName = fPickName;
310 to.fColour = c;
311 to.fStartTime = fpVisAttribs->GetStartTime();
312 to.fEndTime = fpVisAttribs->GetEndTime();
313 to.fMarkerOrPolyline = isMarkerOrPolyline;
314 fTOList.push_back(to);
315 // For transient objects, colour, transformation, are kept in
316 // the TO, so should *not* be in the display list. As mentioned
317 // above, in some cases (display-by-time fading) we need to have
318 // independent control of colour. But for now transform and set
319 // colour for immediate display.
320 glPushMatrix();
322 glMultMatrixd (oglt.GetGLMatrix ());
323 if (transparency_enabled) {
324 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
325 } else {
326 glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
327 }
328 (void) ExtraTOProcessing(visible, fTOList.size() - 1);
329 // Ignore return value of the above. If this visible does not use
330 // gl commands, a display list is created that is empty and not
331 // used.
332 glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
333 } else {
335 if (isPicking) po.fPickName = fPickName;
336 po.fColour = c;
337 po.fMarkerOrPolyline = isMarkerOrPolyline;
338 fPOList.push_back(po);
339 // For permanent objects, colour is kept in the PO, so should
340 // *not* be in the display list. This is so that sub-classes
341 // may implement colour modifications according to their own
342 // criteria, e.g., scene tree slider in Qt. But for now set
343 // colour for immediate display.
344 if (transparency_enabled) {
345 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
346 } else {
347 glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
348 }
349 G4bool usesGLCommands = ExtraPOProcessing(visible, fPOList.size() - 1);
350 // Transients are displayed as they come (GL_COMPILE_AND_EXECUTE
351 // above) but persistents are compiled into display lists
352 // (GL_COMPILE only) and then drawn from the display lists with
353 // their fObjectTransformation as stored in fPOList. Thus,
354 // there is no need to do glMultMatrixd here. If
355 // ExtraPOProcessing says the visible object does not use gl
356 // commands, simply return and abandon further processing. It
357 // is assumed that all relevant information is kept in the
358 // POList.
359 if (!usesGLCommands) return false;
360 glNewList (fDisplayListId, GL_COMPILE);
361 }
362 }
363
364 if (fProcessing2D) {
365 // Push current 3D world matrices and load identity to define screen
366 // coordinates...
367 glMatrixMode (GL_PROJECTION);
368 glPushMatrix();
369 glLoadIdentity();
370 if (pOGLViewer) {
371 pOGLViewer->g4GlOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
372 }
373 glMatrixMode (GL_MODELVIEW);
374 glPushMatrix();
375 glLoadIdentity();
377 glMultMatrixd (oglt.GetGLMatrix ());
378 glDisable (GL_LIGHTING);
379 } else {
380 if (isMarker) {
381 glDisable (GL_LIGHTING);
382 } else {
383 glEnable (GL_LIGHTING);
384 }
385 }
386
387 return true;
388}
389
391{
392 if (fProcessing2D) {
393 // Pop current 3D world matrices back again...
394 glMatrixMode (GL_PROJECTION);
395 glPopMatrix();
396 glMatrixMode (GL_MODELVIEW);
397 glPopMatrix();
398 }
399
400 // if ((glGetError() == GL_TABLE_TOO_LARGE) || (glGetError() == GL_OUT_OF_MEMORY)) { // Could close?
401 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close?
402 G4cerr <<
403 "ERROR: G4OpenGLStoredSceneHandler::AddPrimitivePostamble: Failure"
404 " to allocate display List for fTopPODL - try OpenGL Immediated mode."
405 << G4endl;
406 }
408 glEndList();
409 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close?
410 G4cerr <<
411 "ERROR: G4OpenGLStoredSceneHandler::AddPrimitivePostamble: Failure"
412 " to allocate display List for fTopPODL - try OpenGL Immediated mode."
413 << G4endl;
414 }
415 }
417 glPopMatrix();
418 }
419}
420
422{
423 G4bool furtherprocessing = AddPrimitivePreamble(polyline);
424 if (furtherprocessing) {
427 }
428}
429
431{
432 G4bool furtherprocessing = AddPrimitivePreamble(polymarker);
433 if (furtherprocessing) {
436 }
437}
438
440{
441 // Note: colour is still handled in
442 // G4OpenGLSceneHandler::AddPrimitive(const G4Text&), so it still
443 // gets into the display list
444 G4bool furtherprocessing = AddPrimitivePreamble(text);
445 if (furtherprocessing) {
448 }
449}
450
452{
453 G4bool furtherprocessing = AddPrimitivePreamble(circle);
454 if (furtherprocessing) {
457 }
458}
459
461{
462 G4bool furtherprocessing = AddPrimitivePreamble(square);
463 if (furtherprocessing) {
466 }
467}
468
470{
471 // Note: colour is still handled in
472 // G4OpenGLSceneHandler::AddPrimitive(const G4Polyhedron&), so it still
473 // gets into the display list
474 G4bool furtherprocessing = AddPrimitivePreamble(polyhedron);
475 if (furtherprocessing) {
478 }
479}
480
483 /* Debug...
484 fDisplayListId = glGenLists (1);
485 G4cout << "OGL::fDisplayListId (start): " << fDisplayListId << G4endl;
486 */
487}
488
490 // Make a List which calls the other lists.
491 fTopPODL = glGenLists (1);
492 if (glGetError() == GL_OUT_OF_MEMORY) { // Could pre-allocate?
493 G4cerr <<
494 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
495 " display List for fTopPODL - try OpenGL Immediated mode."
496 << G4endl;
497 } else {
498
499 glNewList (fTopPODL, GL_COMPILE); {
500 for (size_t i = 0; i < fPOList.size (); i++) {
501 glPushMatrix();
502 G4OpenGLTransform3D oglt (fPOList[i].fTransform);
503 glMultMatrixd (oglt.GetGLMatrix ());
505 glLoadName(fPOList[i].fPickName);
506 glCallList (fPOList[i].fDisplayListId);
507 glPopMatrix();
508 }
509 }
510 glEndList ();
511
512 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close?
513 G4cerr <<
514 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
515 " display List for fTopPODL - try OpenGL Immediated mode."
516 << G4endl;
517 }
518 }
519
521}
522
524
525 //G4cout << "G4OpenGLStoredSceneHandler::ClearStore" << G4endl;
526
527 G4VSceneHandler::ClearStore (); // Sets need kernel visit, etc.
528
529 // Delete OpenGL permanent display lists.
530 for (size_t i = 0; i < fPOList.size (); i++)
531 glDeleteLists (fPOList[i].fDisplayListId, 1);
532 if (fTopPODL) glDeleteLists (fTopPODL, 1);
533 fTopPODL = 0;
534
535 // Clear other lists, dictionary, etc.
536 fPOList.clear ();
537 fSolidMap.clear ();
539
540 // ...and clear transient store...
541 for (size_t i = 0; i < fTOList.size (); i++)
542 glDeleteLists(fTOList[i].fDisplayListId, 1);
543 fTOList.clear ();
544}
545
547{
548 //G4cout << "G4OpenGLStoredSceneHandler::ClearTransientStore" << G4endl;
549
550 // Delete OpenGL transient display lists and Transient Objects themselves.
551 for (size_t i = 0; i < fTOList.size (); i++)
552 glDeleteLists(fTOList[i].fDisplayListId, 1);
553 fTOList.clear ();
554
555 // Redraw the scene ready for the next event.
556 if (fpViewer) {
557 fpViewer -> SetView ();
558 fpViewer -> ClearView ();
559 fpViewer -> DrawView ();
560 }
561}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
#define G4OPENGL_FLT_BIG
Definition: G4OpenGL.hh:89
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
G4double GetBlue() const
Definition: G4Colour.hh:154
G4double GetAlpha() const
Definition: G4Colour.hh:155
G4double GetRed() const
Definition: G4Colour.hh:152
G4double GetGreen() const
Definition: G4Colour.hh:153
virtual void BeginPrimitives2D(const G4Transform3D &objectTransformation)
void AddPrimitive(const G4Polyline &)
virtual void BeginPrimitives(const G4Transform3D &objectTransformation)
std::map< GLuint, G4AttHolder * > fPickMap
virtual G4bool ExtraPOProcessing(const G4Visible &, size_t)
std::map< const G4VSolid *, G4int, std::less< const G4VSolid * > > fSolidMap
void AddPrimitive(const G4Polyline &)
G4bool AddPrimitivePreamble(const G4VMarker &visible)
G4OpenGLStoredSceneHandler(G4VGraphicsSystem &system, const G4String &name="")
virtual G4bool ExtraTOProcessing(const G4Visible &, size_t)
void BeginPrimitives(const G4Transform3D &objectTransformation)
void BeginPrimitives2D(const G4Transform3D &objectTransformation)
const GLdouble * GetGLMatrix()
G4bool transparency_enabled
void g4GlOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)
Definition: G4Text.hh:72
virtual void BeginModeling()
void LoadAtts(const G4Visible &, G4AttHolder *)
const G4Colour & GetColour()
G4Transform3D fObjectTransformation
virtual void EndModeling()
G4VViewer * fpViewer
const G4VisAttributes * fpVisAttribs
virtual void ClearStore()
const G4VisAttributes * GetApplicableVisAttributes(const G4VisAttributes *) const
const G4ViewParameters & GetViewParameters() const
G4ViewParameters fVP
Definition: G4VViewer.hh:220
G4bool IsMarkerNotHidden() const
G4bool IsPicking() const
G4double GetStartTime() const
G4double GetEndTime() const
const G4VisAttributes * GetVisAttributes() const