Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // 26 // >> 27 // $Id: G4OpenGLStoredSceneHandler.cc,v 1.40 2009/02/04 16:48:41 lgarnier Exp $ >> 28 // GEANT4 tag $Name: geant4-09-03-patch-02 $ 27 // 29 // 28 // 30 // 29 // Andrew Walkden 10th February 1997 31 // Andrew Walkden 10th February 1997 30 // OpenGL stored scene - creates OpenGL displa 32 // OpenGL stored scene - creates OpenGL display lists. 31 33 >> 34 #ifdef G4VIS_BUILD_OPENGL_DRIVER >> 35 >> 36 // Included here - problems with HP compiler if not before other includes? >> 37 #include "G4NURBS.hh" >> 38 >> 39 // Here follows a special for Mesa, the OpenGL emulator. Does not affect >> 40 // other OpenGL's, as far as I'm aware. John Allison 18/9/96. >> 41 #define CENTERLINE_CLPP /* CenterLine C++ workaround: */ >> 42 // Also seems to be required for HP's CC and AIX xlC, at least. >> 43 32 #include "G4OpenGLStoredSceneHandler.hh" 44 #include "G4OpenGLStoredSceneHandler.hh" 33 45 34 #include "G4PhysicalVolumeModel.hh" 46 #include "G4PhysicalVolumeModel.hh" 35 #include "G4LogicalVolumeModel.hh" << 36 #include "G4VPhysicalVolume.hh" 47 #include "G4VPhysicalVolume.hh" 37 #include "G4LogicalVolume.hh" 48 #include "G4LogicalVolume.hh" 38 #include "G4Polyline.hh" 49 #include "G4Polyline.hh" 39 #include "G4Polymarker.hh" 50 #include "G4Polymarker.hh" 40 #include "G4Text.hh" 51 #include "G4Text.hh" 41 #include "G4Circle.hh" 52 #include "G4Circle.hh" 42 #include "G4Square.hh" 53 #include "G4Square.hh" 43 #include "G4Polyhedron.hh" 54 #include "G4Polyhedron.hh" 44 #include "G4AttHolder.hh" 55 #include "G4AttHolder.hh" 45 #include "G4OpenGLTransform3D.hh" 56 #include "G4OpenGLTransform3D.hh" 46 #include "G4OpenGLViewer.hh" 57 #include "G4OpenGLViewer.hh" 47 #include "G4AttHolder.hh" << 48 << 49 #include <typeinfo> << 50 << 51 G4int G4OpenGLStoredSceneHandler::fSceneIdCoun << 52 << 53 G4int G4OpenGLStoredSceneHandler::fDisplayLis << 54 << 55 G4OpenGLStoredSceneHandler::PO::PO(): << 56 fDisplayListId(0), << 57 fPickName(0), << 58 fpG4TextPlus(0), << 59 fMarkerOrPolyline(false) << 60 {} << 61 << 62 G4OpenGLStoredSceneHandler::PO::PO(const G4Ope << 63 fDisplayListId(po.fDisplayListId), << 64 fTransform(po.fTransform), << 65 fPickName(po.fPickName), << 66 fColour(po.fColour), << 67 fpG4TextPlus(po.fpG4TextPlus? new G4TextPlus << 68 fMarkerOrPolyline(po.fMarkerOrPolyline) << 69 {} << 70 58 71 G4OpenGLStoredSceneHandler::PO::PO(G4int id, c << 59 G4OpenGLStoredSceneHandler::PO::PO >> 60 (G4int id, >> 61 const G4Transform3D& tr): 72 fDisplayListId(id), 62 fDisplayListId(id), 73 fTransform(tr), 63 fTransform(tr), 74 fPickName(0), << 64 fPickName(0) 75 fpG4TextPlus(0), << 76 fMarkerOrPolyline(false) << 77 {} << 78 << 79 G4OpenGLStoredSceneHandler::PO::~PO() << 80 { << 81 delete fpG4TextPlus; << 82 } << 83 << 84 G4OpenGLStoredSceneHandler::PO& G4OpenGLStored << 85 (const G4OpenGLStoredSceneHandler::PO& rhs) << 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 G4TextP << 93 fMarkerOrPolyline = rhs.fMarkerOrPolyline; << 94 return *this; << 95 } << 96 << 97 G4OpenGLStoredSceneHandler::TO::TO(): << 98 fDisplayListId(0), << 99 fPickName(0), << 100 fStartTime(-G4VisAttributes::fVeryLongTime), << 101 fEndTime(G4VisAttributes::fVeryLongTime), << 102 fpG4TextPlus(0), << 103 fMarkerOrPolyline(false) << 104 {} << 105 << 106 G4OpenGLStoredSceneHandler::TO::TO(const G4Ope << 107 fDisplayListId(to.fDisplayListId), << 108 fTransform(to.fTransform), << 109 fPickName(to.fPickName), << 110 fStartTime(to.fStartTime), << 111 fEndTime(to.fEndTime), << 112 fColour(to.fColour), << 113 fpG4TextPlus(to.fpG4TextPlus? new G4TextPlus << 114 fMarkerOrPolyline(to.fMarkerOrPolyline) << 115 {} 65 {} 116 66 117 G4OpenGLStoredSceneHandler::TO::TO(G4int id, c << 67 G4OpenGLStoredSceneHandler::TO::TO >> 68 (G4int id, >> 69 const G4Transform3D& tr): 118 fDisplayListId(id), 70 fDisplayListId(id), 119 fTransform(tr), 71 fTransform(tr), 120 fPickName(0), 72 fPickName(0), 121 fStartTime(-G4VisAttributes::fVeryLongTime), << 73 fStartTime(-DBL_MAX), 122 fEndTime(G4VisAttributes::fVeryLongTime), << 74 fEndTime(DBL_MAX) 123 fpG4TextPlus(0), << 124 fMarkerOrPolyline(false) << 125 {} 75 {} 126 76 127 G4OpenGLStoredSceneHandler::TO::~TO() << 128 { << 129 delete fpG4TextPlus; << 130 } << 131 << 132 G4OpenGLStoredSceneHandler::TO& G4OpenGLStored << 133 (const G4OpenGLStoredSceneHandler::TO& rhs) << 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 G4TextP << 143 fMarkerOrPolyline = rhs.fMarkerOrPolyline; << 144 return *this; << 145 } << 146 << 147 G4OpenGLStoredSceneHandler::G4OpenGLStoredScen 77 G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler 148 (G4VGraphicsSystem& system, 78 (G4VGraphicsSystem& system, 149 const G4String& name): 79 const G4String& name): 150 G4OpenGLSceneHandler (system, fSceneIdCount++, 80 G4OpenGLSceneHandler (system, fSceneIdCount++, name), 151 fDoNotUseDisplayList(false), << 81 fMemoryForDisplayLists (true), >> 82 fAddPrimitivePreambleNestingDepth (0), 152 fTopPODL (0) 83 fTopPODL (0) 153 {} 84 {} 154 85 155 G4OpenGLStoredSceneHandler::~G4OpenGLStoredSce 86 G4OpenGLStoredSceneHandler::~G4OpenGLStoredSceneHandler () 156 {} 87 {} 157 88 158 void G4OpenGLStoredSceneHandler::BeginPrimitiv << 89 void G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Visible& visible) 159 (const G4Transform3D& objectTransformation) << 160 { << 161 G4OpenGLSceneHandler::BeginPrimitives (objec << 162 if (fReadyForTransients) glDrawBuffer (GL_FR << 163 // Display list setup moved to AddPrimitiveP << 164 } << 165 << 166 void G4OpenGLStoredSceneHandler::EndPrimitives << 167 { << 168 // See all primitives immediately... At lea << 169 ScaledFlush(); << 170 glDrawBuffer (GL_BACK); << 171 G4OpenGLSceneHandler::EndPrimitives (); << 172 } << 173 << 174 void G4OpenGLStoredSceneHandler::BeginPrimitiv << 175 (const G4Transform3D& objectTransformation) << 176 { << 177 G4OpenGLSceneHandler::BeginPrimitives2D(obje << 178 if (fReadyForTransients) glDrawBuffer (GL_FR << 179 } << 180 << 181 void G4OpenGLStoredSceneHandler::EndPrimitives << 182 { << 183 // See all primitives immediately... At lea << 184 ScaledFlush(); << 185 glDrawBuffer (GL_BACK); << 186 G4OpenGLSceneHandler::EndPrimitives2D (); << 187 } << 188 << 189 G4bool G4OpenGLStoredSceneHandler::AddPrimitiv << 190 { << 191 return AddPrimitivePreambleInternal(visible, << 192 } << 193 G4bool G4OpenGLStoredSceneHandler::AddPrimitiv << 194 { << 195 return AddPrimitivePreambleInternal(visible, << 196 } << 197 G4bool G4OpenGLStoredSceneHandler::AddPrimitiv << 198 { << 199 return AddPrimitivePreambleInternal(visible, << 200 } << 201 << 202 G4bool G4OpenGLStoredSceneHandler::AddPrimitiv << 203 (const G4Visible& visible, bool isMarker, bool << 204 { 90 { 205 // Get applicable vis attributes for all primi << 91 // Track nesting depth to avoid recursive calls, for example, from a 206 fpVisAttribs = fpViewer->GetApplicableVisAtt << 92 // G4Polymarker that invokes a G4Circle... 207 const G4Colour& c = GetColour (); << 93 fAddPrimitivePreambleNestingDepth++; 208 G4double opacity = c.GetAlpha (); << 94 if (fAddPrimitivePreambleNestingDepth > 1) return; 209 << 210 G4bool transparency_enabled = true; << 211 G4bool isMarkerNotHidden = true; << 212 G4OpenGLViewer* pOGLViewer = dynamic_cast<G4 << 213 if (pOGLViewer) { << 214 transparency_enabled = pOGLViewer->transpa << 215 isMarkerNotHidden = pOGLViewer->fVP.IsMark << 216 } << 217 << 218 G4bool isTransparent = opacity < 1.; << 219 G4bool isMarkerOrPolyline = isMarker || isPo << 220 G4bool treatAsTransparent = transparency_ena << 221 G4bool treatAsNotHidden = isMarkerNotHidden << 222 << 223 if (fProcessing2D) glDisable (GL_DEPTH_TEST) << 224 else { << 225 if (isMarkerOrPolyline && isMarkerNotHidde << 226 glDisable (GL_DEPTH_TEST); << 227 else {glEnable (GL_DEPTH_TEST); glDepthFun << 228 } << 229 << 230 if (fThreePassCapable) { << 231 << 232 // Ensure transparent objects are drawn *a << 233 // non-hidden markers. The problem of ble << 234 // is quite a tricky one - see History of << 235 if (!(fSecondPassForTransparency || fThird << 236 // First pass... << 237 if (treatAsTransparent) { // Request pa << 238 fSecondPassForTransparencyRequested = << 239 } << 240 if (treatAsNotHidden) { // Request pa << 241 fThirdPassForNonHiddenMarkersRequested << 242 } << 243 // On first pass, transparent objects an << 244 if (treatAsTransparent || treatAsNotHidd << 245 return false; // No further processin << 246 } << 247 } << 248 << 249 // On second pass, only transparent object << 250 if (fSecondPassForTransparency) { << 251 if (!treatAsTransparent) { << 252 return false; // No further processin << 253 } << 254 } << 255 << 256 // On third pass, only non-hidden markers << 257 if (fThirdPassForNonHiddenMarkers) { << 258 if (!treatAsNotHidden) { << 259 return false; // No further processin << 260 } << 261 } << 262 } // fThreePassCapable << 263 << 264 // Loads G4Atts for picking... << 265 G4bool isPicking = false; << 266 if (fpViewer->GetViewParameters().IsPicking( << 267 isPicking = true; << 268 glLoadName(++fPickName); << 269 G4AttHolder* holder = new G4AttHolder; << 270 LoadAtts(visible, holder); << 271 fPickMap[fPickName] = holder; << 272 } << 273 95 274 // Because of our need to control colour of 96 // Because of our need to control colour of transients (display by 275 // time fading), display lists may only cove 97 // time fading), display lists may only cover a single primitive. 276 // So display list setup is here. 98 // So display list setup is here. 277 99 278 if (fDoNotUseDisplayList) { << 100 if (fpViewer->GetViewParameters().IsPicking()) { 279 << 101 fPickMap[++fPickName] = 0; 280 glPushMatrix(); << 102 } 281 G4OpenGLTransform3D oglt (fObjectTransform << 282 glMultMatrixd (oglt.GetGLMatrix ()); << 283 if (transparency_enabled) { << 284 glColor4d(c.GetRed(),c.GetGreen(),c.GetB << 285 } else { << 286 glColor3d(c.GetRed(),c.GetGreen(),c.GetB << 287 } << 288 103 289 } else { << 104 const G4Colour& c = GetColour (visible); 290 105 >> 106 if (fMemoryForDisplayLists) { 291 fDisplayListId = glGenLists (1); 107 fDisplayListId = glGenLists (1); 292 if (glGetError() == GL_OUT_OF_MEMORY) { << 108 if (glGetError() == GL_OUT_OF_MEMORY) { // Could pre-allocate? 293 static G4int errorCount = 0; << 109 G4cout << 294 if (errorCount < 5) { << 110 "********************* WARNING! ********************" 295 errorCount++; << 111 "\nUnable to allocate any more display lists in OpenGL." 296 G4ExceptionDescription ed; << 112 "\n Continuing drawing in IMMEDIATE MODE." 297 ed << << 113 "\n***************************************************" 298 "Error attempting to create an OpenGL << 114 << G4endl; 299 "\nCurrent display list id: " << fDisp << 115 fMemoryForDisplayLists = false; 300 "\nMaybe out of memory?"; << 301 G4Exception << 302 ("G4OpenGLStoredSceneHandler::AddPrimi << 303 JustWarning,ed); << 304 } << 305 return false; << 306 } 116 } >> 117 } >> 118 if (fMemoryForDisplayLists) { 307 if (fReadyForTransients) { 119 if (fReadyForTransients) { 308 TO to(fDisplayListId, fObjectTransformat << 120 TO to(fDisplayListId, *fpObjectTransformation); 309 if (isPicking) to.fPickName = fPickName; << 121 to.fPickName = fPickName; 310 to.fColour = c; 122 to.fColour = c; 311 to.fStartTime = fpVisAttribs->GetStartTi << 123 const G4VisAttributes* pVA = 312 to.fEndTime = fpVisAttribs->GetEndTime() << 124 fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes()); 313 to.fMarkerOrPolyline = isMarkerOrPolylin << 125 to.fStartTime = pVA->GetStartTime(); >> 126 to.fEndTime = pVA->GetEndTime(); 314 fTOList.push_back(to); 127 fTOList.push_back(to); 315 // For transient objects, colour, transf << 128 glDrawBuffer (GL_FRONT); 316 // the TO, so should *not* be in the dis << 317 // above, in some cases (display-by-time << 318 // independent control of colour. But f << 319 // colour for immediate display. << 320 glPushMatrix(); 129 glPushMatrix(); 321 G4OpenGLTransform3D oglt (fObjectTransfo << 130 G4OpenGLTransform3D oglt (*fpObjectTransformation); 322 glMultMatrixd (oglt.GetGLMatrix ()); 131 glMultMatrixd (oglt.GetGLMatrix ()); 323 if (transparency_enabled) { << 132 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ()); 324 glColor4d(c.GetRed(),c.GetGreen(),c.Ge << 325 } else { << 326 glColor3d(c.GetRed(),c.GetGreen(),c.Ge << 327 } << 328 (void) ExtraTOProcessing(visible, fTOLis << 329 // Ignore return value of the above. If << 330 // gl commands, a display list is create << 331 // used. << 332 glNewList (fDisplayListId, GL_COMPILE_AN 133 glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE); 333 } else { << 134 } 334 PO po(fDisplayListId, fObjectTransformat << 135 else { 335 if (isPicking) po.fPickName = fPickName; << 136 PO po(fDisplayListId, *fpObjectTransformation); 336 po.fColour = c; << 137 po.fPickName = fPickName; 337 po.fMarkerOrPolyline = isMarkerOrPolylin << 338 fPOList.push_back(po); 138 fPOList.push_back(po); 339 // For permanent objects, colour is kept << 340 // *not* be in the display list. This i << 341 // may implement colour modifications ac << 342 // criteria, e.g., scene tree slider in << 343 // colour for immediate display. << 344 if (transparency_enabled) { << 345 glColor4d(c.GetRed(),c.GetGreen(),c.Ge << 346 } else { << 347 glColor3d(c.GetRed(),c.GetGreen(),c.Ge << 348 } << 349 G4bool usesGLCommands = ExtraPOProcessin << 350 // Transients are displayed as they come << 351 // above) but persistents are compiled i << 352 // (GL_COMPILE only) and then drawn from << 353 // their fObjectTransformation as stored << 354 // there is no need to do glMultMatrixd << 355 // ExtraPOProcessing says the visible ob << 356 // commands, simply return and abandon f << 357 // is assumed that all relevant informat << 358 // POList. << 359 if (!usesGLCommands) return false; << 360 glNewList (fDisplayListId, GL_COMPILE); 139 glNewList (fDisplayListId, GL_COMPILE); >> 140 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ()); 361 } 141 } >> 142 } else { >> 143 glDrawBuffer (GL_FRONT); >> 144 glPushMatrix(); >> 145 G4OpenGLTransform3D oglt (*fpObjectTransformation); >> 146 glMultMatrixd (oglt.GetGLMatrix ()); >> 147 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ()); 362 } 148 } 363 149 364 if (fProcessing2D) { 150 if (fProcessing2D) { 365 // Push current 3D world matrices and load 151 // Push current 3D world matrices and load identity to define screen 366 // coordinates... 152 // coordinates... 367 glMatrixMode (GL_PROJECTION); 153 glMatrixMode (GL_PROJECTION); 368 glPushMatrix(); 154 glPushMatrix(); 369 glLoadIdentity(); 155 glLoadIdentity(); 370 if (pOGLViewer) { << 156 glOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG); 371 pOGLViewer->g4GlOrtho (-1., 1., -1., 1., << 372 } << 373 glMatrixMode (GL_MODELVIEW); 157 glMatrixMode (GL_MODELVIEW); 374 glPushMatrix(); 158 glPushMatrix(); 375 glLoadIdentity(); 159 glLoadIdentity(); 376 G4OpenGLTransform3D oglt (fObjectTransform << 160 G4OpenGLTransform3D oglt (*fpObjectTransformation); 377 glMultMatrixd (oglt.GetGLMatrix ()); 161 glMultMatrixd (oglt.GetGLMatrix ()); 378 glDisable (GL_LIGHTING); << 162 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ()); 379 } else { << 380 if (isMarker) { << 381 glDisable (GL_LIGHTING); << 382 } else { << 383 glEnable (GL_LIGHTING); << 384 } << 385 } 163 } 386 << 387 return true; << 388 } 164 } 389 165 390 void G4OpenGLStoredSceneHandler::AddPrimitiveP 166 void G4OpenGLStoredSceneHandler::AddPrimitivePostamble() 391 { 167 { 392 if (fProcessing2D) { 168 if (fProcessing2D) { 393 // Pop current 3D world matrices back agai 169 // Pop current 3D world matrices back again... 394 glMatrixMode (GL_PROJECTION); 170 glMatrixMode (GL_PROJECTION); 395 glPopMatrix(); 171 glPopMatrix(); 396 glMatrixMode (GL_MODELVIEW); 172 glMatrixMode (GL_MODELVIEW); 397 glPopMatrix(); 173 glPopMatrix(); 398 } 174 } 399 175 400 // if ((glGetError() == GL_TABLE_TOO_LARGE) 176 // if ((glGetError() == GL_TABLE_TOO_LARGE) || (glGetError() == GL_OUT_OF_MEMORY)) { // Could close? 401 if (glGetError() == GL_OUT_OF_MEMORY) { // 177 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close? 402 G4cerr << << 178 G4cout << 403 "ERROR: G4OpenGLStoredSceneHandler::AddP << 179 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate" 404 " to allocate display List for fTopPODL << 180 " display List for fTopPODL - try OpenGL Immediated mode." 405 << G4endl; 181 << G4endl; 406 } 182 } 407 if (!fDoNotUseDisplayList) { << 183 if (fMemoryForDisplayLists) { 408 glEndList(); 184 glEndList(); 409 if (glGetError() == GL_OUT_OF_MEMORY) { / 185 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close? 410 G4cerr << << 186 G4cout << 411 "ERROR: G4OpenGLStoredSceneHandler::Ad << 187 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate" 412 " to allocate display List for fTopPODL - t << 188 " display List for fTopPODL - try OpenGL Immediated mode." 413 << G4endl; 189 << G4endl; 414 } 190 } 415 } 191 } 416 if (fReadyForTransients || fDoNotUseDisplayL << 192 if (fReadyForTransients || !fMemoryForDisplayLists) { 417 glPopMatrix(); 193 glPopMatrix(); >> 194 glFlush (); >> 195 glDrawBuffer (GL_BACK); 418 } 196 } >> 197 fAddPrimitivePreambleNestingDepth--; 419 } 198 } 420 199 421 void G4OpenGLStoredSceneHandler::AddPrimitive 200 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline) 422 { 201 { 423 G4bool furtherprocessing = AddPrimitivePream << 202 AddPrimitivePreamble(polyline); 424 if (furtherprocessing) { << 203 G4OpenGLSceneHandler::AddPrimitive(polyline); 425 G4OpenGLSceneHandler::AddPrimitive(polylin << 204 AddPrimitivePostamble(); 426 AddPrimitivePostamble(); << 427 } << 428 } 205 } 429 206 430 void G4OpenGLStoredSceneHandler::AddPrimitive 207 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker) 431 { 208 { 432 G4bool furtherprocessing = AddPrimitivePream << 209 AddPrimitivePreamble(polymarker); 433 if (furtherprocessing) { << 210 G4OpenGLSceneHandler::AddPrimitive(polymarker); 434 G4OpenGLSceneHandler::AddPrimitive(polymar << 211 AddPrimitivePostamble(); 435 AddPrimitivePostamble(); << 436 } << 437 } 212 } 438 213 439 void G4OpenGLStoredSceneHandler::AddPrimitive 214 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Text& text) 440 { 215 { 441 // Note: colour is still handled in 216 // Note: colour is still handled in 442 // G4OpenGLSceneHandler::AddPrimitive(const 217 // G4OpenGLSceneHandler::AddPrimitive(const G4Text&), so it still 443 // gets into the display list 218 // gets into the display list 444 G4bool furtherprocessing = AddPrimitivePream << 219 AddPrimitivePreamble(text); 445 if (furtherprocessing) { << 220 G4OpenGLSceneHandler::AddPrimitive(text); 446 G4OpenGLSceneHandler::AddPrimitive(text); << 221 AddPrimitivePostamble(); 447 AddPrimitivePostamble(); << 448 } << 449 } 222 } 450 223 451 void G4OpenGLStoredSceneHandler::AddPrimitive 224 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle) 452 { 225 { 453 G4bool furtherprocessing = AddPrimitivePream << 226 AddPrimitivePreamble(circle); 454 if (furtherprocessing) { << 227 G4OpenGLSceneHandler::AddPrimitive(circle); 455 G4OpenGLSceneHandler::AddPrimitive(circle) << 228 AddPrimitivePostamble(); 456 AddPrimitivePostamble(); << 457 } << 458 } 229 } 459 230 460 void G4OpenGLStoredSceneHandler::AddPrimitive 231 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square) 461 { 232 { 462 G4bool furtherprocessing = AddPrimitivePream << 233 AddPrimitivePreamble(square); 463 if (furtherprocessing) { << 234 G4OpenGLSceneHandler::AddPrimitive(square); 464 G4OpenGLSceneHandler::AddPrimitive(square) << 235 AddPrimitivePostamble(); 465 AddPrimitivePostamble(); << 236 } 466 } << 237 >> 238 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Scale& scale) >> 239 { >> 240 // Let base class split into primitives. >> 241 G4OpenGLSceneHandler::AddPrimitive(scale); 467 } 242 } 468 243 469 void G4OpenGLStoredSceneHandler::AddPrimitive 244 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) 470 { 245 { 471 // Note: colour is still handled in 246 // Note: colour is still handled in 472 // G4OpenGLSceneHandler::AddPrimitive(const 247 // G4OpenGLSceneHandler::AddPrimitive(const G4Polyhedron&), so it still 473 // gets into the display list 248 // gets into the display list 474 G4bool furtherprocessing = AddPrimitivePream << 249 AddPrimitivePreamble(polyhedron); 475 if (furtherprocessing) { << 250 G4OpenGLSceneHandler::AddPrimitive(polyhedron); 476 G4OpenGLSceneHandler::AddPrimitive(polyhed << 251 AddPrimitivePostamble(); 477 AddPrimitivePostamble(); << 252 } 478 } << 253 >> 254 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4NURBS& nurbs) >> 255 { >> 256 // Note: colour is still handled in >> 257 // G4OpenGLSceneHandler::AddPrimitive(const G4NURBS&), so it still >> 258 // gets into the display list >> 259 AddPrimitivePreamble(nurbs); >> 260 G4OpenGLSceneHandler::AddPrimitive(nurbs); >> 261 AddPrimitivePostamble(); >> 262 } >> 263 >> 264 void G4OpenGLStoredSceneHandler::BeginPrimitives >> 265 (const G4Transform3D& objectTransformation) >> 266 { >> 267 G4OpenGLSceneHandler::BeginPrimitives (objectTransformation); >> 268 >> 269 // Display list setup moved to AddPrimitivePreamble. See notes there. >> 270 } >> 271 >> 272 void G4OpenGLStoredSceneHandler::EndPrimitives () >> 273 { >> 274 G4OpenGLSceneHandler::EndPrimitives (); >> 275 } >> 276 >> 277 void G4OpenGLStoredSceneHandler::BeginPrimitives2D >> 278 (const G4Transform3D& objectTransformation) >> 279 { >> 280 G4OpenGLSceneHandler::BeginPrimitives2D(objectTransformation); >> 281 } >> 282 >> 283 void G4OpenGLStoredSceneHandler::EndPrimitives2D () >> 284 { >> 285 G4OpenGLSceneHandler::EndPrimitives2D (); 479 } 286 } 480 287 481 void G4OpenGLStoredSceneHandler::BeginModeling 288 void G4OpenGLStoredSceneHandler::BeginModeling () { 482 G4VSceneHandler::BeginModeling(); 289 G4VSceneHandler::BeginModeling(); >> 290 ClearStore(); // ...and all that goes with it. 483 /* Debug... 291 /* Debug... 484 fDisplayListId = glGenLists (1); 292 fDisplayListId = glGenLists (1); 485 G4cout << "OGL::fDisplayListId (start): " << 293 G4cout << "OGL::fDisplayListId (start): " << fDisplayListId << G4endl; 486 */ 294 */ 487 } 295 } 488 296 489 void G4OpenGLStoredSceneHandler::EndModeling ( 297 void G4OpenGLStoredSceneHandler::EndModeling () { 490 // Make a List which calls the other lists. 298 // Make a List which calls the other lists. 491 fTopPODL = glGenLists (1); 299 fTopPODL = glGenLists (1); 492 if (glGetError() == GL_OUT_OF_MEMORY) { // 300 if (glGetError() == GL_OUT_OF_MEMORY) { // Could pre-allocate? 493 G4cerr << << 301 G4cout << 494 "ERROR: G4OpenGLStoredSceneHandler::EndM 302 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate" 495 " display List for fTopPODL - try OpenG 303 " display List for fTopPODL - try OpenGL Immediated mode." 496 << G4endl; 304 << G4endl; 497 } else { 305 } else { 498 << 306 glNewList (fTopPODL, GL_COMPILE_AND_EXECUTE); { 499 glNewList (fTopPODL, GL_COMPILE); { << 500 for (size_t i = 0; i < fPOList.size (); 307 for (size_t i = 0; i < fPOList.size (); i++) { 501 glPushMatrix(); 308 glPushMatrix(); 502 G4OpenGLTransform3D oglt (fPOList[i].fTransf 309 G4OpenGLTransform3D oglt (fPOList[i].fTransform); 503 glMultMatrixd (oglt.GetGLMatrix ()); 310 glMultMatrixd (oglt.GetGLMatrix ()); 504 if (fpViewer->GetViewParameters().IsPicking( 311 if (fpViewer->GetViewParameters().IsPicking()) 505 glLoadName(fPOList[i].fPickName); 312 glLoadName(fPOList[i].fPickName); 506 glCallList (fPOList[i].fDisplayListId); 313 glCallList (fPOList[i].fDisplayListId); 507 glPopMatrix(); 314 glPopMatrix(); 508 } 315 } 509 } 316 } 510 glEndList (); 317 glEndList (); 511 << 512 if (glGetError() == GL_OUT_OF_MEMORY) { / 318 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close? 513 G4cerr << << 319 G4cout << 514 "ERROR: G4OpenGLStoredSceneHandler::En 320 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate" 515 " display List for fTopPODL - try Ope 321 " display List for fTopPODL - try OpenGL Immediated mode." 516 << G4endl; 322 << G4endl; 517 } 323 } 518 } 324 } 519 325 520 G4VSceneHandler::EndModeling (); 326 G4VSceneHandler::EndModeling (); >> 327 >> 328 /* Debug... >> 329 fDisplayListId = glGenLists (1); >> 330 G4cout << "OGL::fDisplayListId (end): " << fDisplayListId << G4endl; >> 331 */ 521 } 332 } 522 333 523 void G4OpenGLStoredSceneHandler::ClearStore () 334 void G4OpenGLStoredSceneHandler::ClearStore () { 524 335 525 //G4cout << "G4OpenGLStoredSceneHandler::Cle << 526 << 527 G4VSceneHandler::ClearStore (); // Sets nee 336 G4VSceneHandler::ClearStore (); // Sets need kernel visit, etc. 528 337 529 // Delete OpenGL permanent display lists. 338 // Delete OpenGL permanent display lists. 530 for (size_t i = 0; i < fPOList.size (); i++) 339 for (size_t i = 0; i < fPOList.size (); i++) 531 glDeleteLists (fPOList[i].fDisplayListId, 340 glDeleteLists (fPOList[i].fDisplayListId, 1); 532 if (fTopPODL) glDeleteLists (fTopPODL, 1); 341 if (fTopPODL) glDeleteLists (fTopPODL, 1); 533 fTopPODL = 0; 342 fTopPODL = 0; 534 343 535 // Clear other lists, dictionary, etc. 344 // Clear other lists, dictionary, etc. 536 fPOList.clear (); 345 fPOList.clear (); 537 fSolidMap.clear (); 346 fSolidMap.clear (); 538 ClearAndDestroyAtts(); 347 ClearAndDestroyAtts(); 539 348 540 // ...and clear transient store... 349 // ...and clear transient store... 541 for (size_t i = 0; i < fTOList.size (); i++) 350 for (size_t i = 0; i < fTOList.size (); i++) 542 glDeleteLists(fTOList[i].fDisplayListId, 1 351 glDeleteLists(fTOList[i].fDisplayListId, 1); 543 fTOList.clear (); 352 fTOList.clear (); 544 } 353 } 545 354 546 void G4OpenGLStoredSceneHandler::ClearTransien << 355 void G4OpenGLStoredSceneHandler::ClearTransientStore () { 547 { << 356 548 //G4cout << "G4OpenGLStoredSceneHandler::Cle << 357 G4VSceneHandler::ClearTransientStore (); 549 358 550 // Delete OpenGL transient display lists and 359 // Delete OpenGL transient display lists and Transient Objects themselves. 551 for (size_t i = 0; i < fTOList.size (); i++) 360 for (size_t i = 0; i < fTOList.size (); i++) 552 glDeleteLists(fTOList[i].fDisplayListId, 1 361 glDeleteLists(fTOList[i].fDisplayListId, 1); 553 fTOList.clear (); 362 fTOList.clear (); 554 363 555 // Redraw the scene ready for the next event << 364 // Make sure screen corresponds to graphical database... 556 if (fpViewer) { 365 if (fpViewer) { 557 fpViewer -> SetView (); 366 fpViewer -> SetView (); 558 fpViewer -> ClearView (); 367 fpViewer -> ClearView (); 559 fpViewer -> DrawView (); 368 fpViewer -> DrawView (); 560 } 369 } 561 } 370 } >> 371 >> 372 void G4OpenGLStoredSceneHandler::RequestPrimitives (const G4VSolid& solid) >> 373 { >> 374 if (fReadyForTransients) { >> 375 // Always draw transient solids, e.g., hits represented as solids. >> 376 // (As we have no control over the order of drawing of transient >> 377 // objects, we cannot do anything about transparent ones, as >> 378 // below, so always draw them.) >> 379 G4VSceneHandler::RequestPrimitives (solid); >> 380 return; >> 381 } >> 382 >> 383 // For non-transient (run-duration) objects, ensure transparent >> 384 // objects are drawn last. The problem of >> 385 // blending/transparency/alpha is quite a tricky one - see History >> 386 // of opengl-V07-01-01/2/3. >> 387 // Get vis attributes - pick up defaults if none. >> 388 const G4VisAttributes* pVA = >> 389 fpViewer -> GetApplicableVisAttributes(fpVisAttribs); >> 390 const G4Colour& c = pVA -> GetColour (); >> 391 G4double opacity = c.GetAlpha (); >> 392 >> 393 if (!fSecondPass) { >> 394 G4bool transparency_enabled = true; >> 395 G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer); >> 396 if (pViewer) transparency_enabled = pViewer->transparency_enabled; >> 397 if (transparency_enabled && opacity < 1.) { >> 398 // On first pass, transparent objects are not drawn, but flag is set... >> 399 fSecondPassRequested = true; >> 400 return; >> 401 } >> 402 } >> 403 >> 404 // On second pass, opaque objects are not drwan... >> 405 if (fSecondPass && opacity >= 1.) return; >> 406 >> 407 G4PhysicalVolumeModel* pPVModel = >> 408 dynamic_cast<G4PhysicalVolumeModel*>(fpModel); >> 409 >> 410 if (pPVModel) { >> 411 // If part of the geometry hierarchy, i.e., from a >> 412 // G4PhysicalVolumeModel, check if a display list already exists for >> 413 // this solid, re-use it if possible. We could be smarter, and >> 414 // recognise repeated branches of the geometry hierarchy, for >> 415 // example. But this algorithm should be secure, I think... >> 416 const G4VSolid* pSolid = &solid; >> 417 EAxis axis = kRho; >> 418 G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV(); >> 419 if (pCurrentPV -> IsReplicated ()) { >> 420 G4int nReplicas; >> 421 G4double width; >> 422 G4double offset; >> 423 G4bool consuming; >> 424 pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming); >> 425 } >> 426 // Provided it is not parametrised (because if so, the >> 427 // solid's parameters might have been changed)... >> 428 if (!(pCurrentPV -> IsParameterised ()) && >> 429 // Provided it is not replicated radially (because if so, the >> 430 // solid's parameters will have been changed)... >> 431 !(pCurrentPV -> IsReplicated () && axis == kRho) && >> 432 // ...and if the solid has already been rendered... >> 433 (fSolidMap.find (pSolid) != fSolidMap.end ())) { >> 434 fDisplayListId = fSolidMap [pSolid]; >> 435 PO po(fDisplayListId,*fpObjectTransformation); >> 436 if (fpViewer->GetViewParameters().IsPicking()) { >> 437 G4AttHolder* holder = new G4AttHolder; >> 438 // Load G4Atts from G4VisAttributes, if any... >> 439 const G4VisAttributes* va = pPVModel->GetCurrentLV()->GetVisAttributes(); >> 440 if (va) { >> 441 const std::map<G4String,G4AttDef>* vaDefs = va->GetAttDefs(); >> 442 if (vaDefs) holder->AddAtts(va->CreateAttValues(), vaDefs); >> 443 } >> 444 // Load G4Atts from G4PhysicalVolumeModel... >> 445 const std::map<G4String,G4AttDef>* defs = pPVModel->GetAttDefs(); >> 446 if (defs) holder->AddAtts(pPVModel->CreateCurrentAttValues(), defs); >> 447 fPickMap[++fPickName] = holder; >> 448 po.fPickName = fPickName; >> 449 } >> 450 fPOList.push_back(po); >> 451 } >> 452 else { >> 453 G4VSceneHandler::RequestPrimitives (solid); >> 454 fSolidMap [pSolid] = fDisplayListId; >> 455 } >> 456 return; >> 457 } >> 458 >> 459 // Otherwise invoke base class method... >> 460 G4VSceneHandler::RequestPrimitives (solid); >> 461 } >> 462 >> 463 G4int G4OpenGLStoredSceneHandler::fSceneIdCount = 0; >> 464 >> 465 #endif 562 466