Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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