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 // 27 // 28 // 28 // 29 // Andrew Walkden 10th February 1997 29 // Andrew Walkden 10th February 1997 30 // OpenGL stored scene - creates OpenGL displa 30 // OpenGL stored scene - creates OpenGL display lists. 31 31 32 #include "G4OpenGLStoredSceneHandler.hh" 32 #include "G4OpenGLStoredSceneHandler.hh" 33 33 34 #include "G4PhysicalVolumeModel.hh" 34 #include "G4PhysicalVolumeModel.hh" 35 #include "G4LogicalVolumeModel.hh" 35 #include "G4LogicalVolumeModel.hh" 36 #include "G4VPhysicalVolume.hh" 36 #include "G4VPhysicalVolume.hh" 37 #include "G4LogicalVolume.hh" 37 #include "G4LogicalVolume.hh" 38 #include "G4Polyline.hh" 38 #include "G4Polyline.hh" 39 #include "G4Polymarker.hh" 39 #include "G4Polymarker.hh" 40 #include "G4Text.hh" 40 #include "G4Text.hh" 41 #include "G4Circle.hh" 41 #include "G4Circle.hh" 42 #include "G4Square.hh" 42 #include "G4Square.hh" 43 #include "G4Polyhedron.hh" 43 #include "G4Polyhedron.hh" 44 #include "G4AttHolder.hh" 44 #include "G4AttHolder.hh" 45 #include "G4OpenGLTransform3D.hh" 45 #include "G4OpenGLTransform3D.hh" 46 #include "G4OpenGLViewer.hh" 46 #include "G4OpenGLViewer.hh" 47 #include "G4AttHolder.hh" 47 #include "G4AttHolder.hh" 48 48 49 #include <typeinfo> 49 #include <typeinfo> 50 50 51 G4int G4OpenGLStoredSceneHandler::fSceneIdCoun 51 G4int G4OpenGLStoredSceneHandler::fSceneIdCount = 0; 52 52 53 G4int G4OpenGLStoredSceneHandler::fDisplayLis 53 G4int G4OpenGLStoredSceneHandler::fDisplayListId = 0; >> 54 G4bool G4OpenGLStoredSceneHandler::fMemoryForDisplayLists = true; >> 55 G4int G4OpenGLStoredSceneHandler::fDisplayListLimit = 1e7; 54 56 55 G4OpenGLStoredSceneHandler::PO::PO(): 57 G4OpenGLStoredSceneHandler::PO::PO(): 56 fDisplayListId(0), 58 fDisplayListId(0), 57 fPickName(0), 59 fPickName(0), 58 fpG4TextPlus(0), 60 fpG4TextPlus(0), 59 fMarkerOrPolyline(false) 61 fMarkerOrPolyline(false) 60 {} 62 {} 61 63 62 G4OpenGLStoredSceneHandler::PO::PO(const G4Ope 64 G4OpenGLStoredSceneHandler::PO::PO(const G4OpenGLStoredSceneHandler::PO& po): 63 fDisplayListId(po.fDisplayListId), 65 fDisplayListId(po.fDisplayListId), 64 fTransform(po.fTransform), 66 fTransform(po.fTransform), 65 fPickName(po.fPickName), 67 fPickName(po.fPickName), 66 fColour(po.fColour), 68 fColour(po.fColour), 67 fpG4TextPlus(po.fpG4TextPlus? new G4TextPlus 69 fpG4TextPlus(po.fpG4TextPlus? new G4TextPlus(*po.fpG4TextPlus): 0), 68 fMarkerOrPolyline(po.fMarkerOrPolyline) 70 fMarkerOrPolyline(po.fMarkerOrPolyline) 69 {} 71 {} 70 72 71 G4OpenGLStoredSceneHandler::PO::PO(G4int id, c 73 G4OpenGLStoredSceneHandler::PO::PO(G4int id, const G4Transform3D& tr): 72 fDisplayListId(id), 74 fDisplayListId(id), 73 fTransform(tr), 75 fTransform(tr), 74 fPickName(0), 76 fPickName(0), 75 fpG4TextPlus(0), 77 fpG4TextPlus(0), 76 fMarkerOrPolyline(false) 78 fMarkerOrPolyline(false) 77 {} 79 {} 78 80 79 G4OpenGLStoredSceneHandler::PO::~PO() 81 G4OpenGLStoredSceneHandler::PO::~PO() 80 { 82 { 81 delete fpG4TextPlus; 83 delete fpG4TextPlus; 82 } 84 } 83 85 84 G4OpenGLStoredSceneHandler::PO& G4OpenGLStored 86 G4OpenGLStoredSceneHandler::PO& G4OpenGLStoredSceneHandler::PO::operator= 85 (const G4OpenGLStoredSceneHandler::PO& rhs) 87 (const G4OpenGLStoredSceneHandler::PO& rhs) 86 { 88 { 87 if (&rhs == this) return *this; 89 if (&rhs == this) return *this; 88 fDisplayListId = rhs.fDisplayListId; 90 fDisplayListId = rhs.fDisplayListId; 89 fTransform = rhs.fTransform; 91 fTransform = rhs.fTransform; 90 fPickName = rhs.fPickName; 92 fPickName = rhs.fPickName; 91 fColour = rhs.fColour; 93 fColour = rhs.fColour; 92 fpG4TextPlus = rhs.fpG4TextPlus? new G4TextP 94 fpG4TextPlus = rhs.fpG4TextPlus? new G4TextPlus(*rhs.fpG4TextPlus): 0; 93 fMarkerOrPolyline = rhs.fMarkerOrPolyline; 95 fMarkerOrPolyline = rhs.fMarkerOrPolyline; 94 return *this; 96 return *this; 95 } 97 } 96 98 97 G4OpenGLStoredSceneHandler::TO::TO(): 99 G4OpenGLStoredSceneHandler::TO::TO(): 98 fDisplayListId(0), 100 fDisplayListId(0), 99 fPickName(0), 101 fPickName(0), 100 fStartTime(-G4VisAttributes::fVeryLongTime), 102 fStartTime(-G4VisAttributes::fVeryLongTime), 101 fEndTime(G4VisAttributes::fVeryLongTime), 103 fEndTime(G4VisAttributes::fVeryLongTime), 102 fpG4TextPlus(0), 104 fpG4TextPlus(0), 103 fMarkerOrPolyline(false) 105 fMarkerOrPolyline(false) 104 {} 106 {} 105 107 106 G4OpenGLStoredSceneHandler::TO::TO(const G4Ope 108 G4OpenGLStoredSceneHandler::TO::TO(const G4OpenGLStoredSceneHandler::TO& to): 107 fDisplayListId(to.fDisplayListId), 109 fDisplayListId(to.fDisplayListId), 108 fTransform(to.fTransform), 110 fTransform(to.fTransform), 109 fPickName(to.fPickName), 111 fPickName(to.fPickName), 110 fStartTime(to.fStartTime), 112 fStartTime(to.fStartTime), 111 fEndTime(to.fEndTime), 113 fEndTime(to.fEndTime), 112 fColour(to.fColour), 114 fColour(to.fColour), 113 fpG4TextPlus(to.fpG4TextPlus? new G4TextPlus 115 fpG4TextPlus(to.fpG4TextPlus? new G4TextPlus(*to.fpG4TextPlus): 0), 114 fMarkerOrPolyline(to.fMarkerOrPolyline) 116 fMarkerOrPolyline(to.fMarkerOrPolyline) 115 {} 117 {} 116 118 117 G4OpenGLStoredSceneHandler::TO::TO(G4int id, c 119 G4OpenGLStoredSceneHandler::TO::TO(G4int id, const G4Transform3D& tr): 118 fDisplayListId(id), 120 fDisplayListId(id), 119 fTransform(tr), 121 fTransform(tr), 120 fPickName(0), 122 fPickName(0), 121 fStartTime(-G4VisAttributes::fVeryLongTime), 123 fStartTime(-G4VisAttributes::fVeryLongTime), 122 fEndTime(G4VisAttributes::fVeryLongTime), 124 fEndTime(G4VisAttributes::fVeryLongTime), 123 fpG4TextPlus(0), 125 fpG4TextPlus(0), 124 fMarkerOrPolyline(false) 126 fMarkerOrPolyline(false) 125 {} 127 {} 126 128 127 G4OpenGLStoredSceneHandler::TO::~TO() 129 G4OpenGLStoredSceneHandler::TO::~TO() 128 { 130 { 129 delete fpG4TextPlus; 131 delete fpG4TextPlus; 130 } 132 } 131 133 132 G4OpenGLStoredSceneHandler::TO& G4OpenGLStored 134 G4OpenGLStoredSceneHandler::TO& G4OpenGLStoredSceneHandler::TO::operator= 133 (const G4OpenGLStoredSceneHandler::TO& rhs) 135 (const G4OpenGLStoredSceneHandler::TO& rhs) 134 { 136 { 135 if (&rhs == this) return *this; 137 if (&rhs == this) return *this; 136 fDisplayListId = rhs.fDisplayListId; 138 fDisplayListId = rhs.fDisplayListId; 137 fTransform = rhs.fTransform; 139 fTransform = rhs.fTransform; 138 fPickName = rhs.fPickName; 140 fPickName = rhs.fPickName; 139 fStartTime = rhs.fStartTime; 141 fStartTime = rhs.fStartTime; 140 fEndTime = rhs.fEndTime; 142 fEndTime = rhs.fEndTime; 141 fColour = rhs.fColour; 143 fColour = rhs.fColour; 142 fpG4TextPlus = rhs.fpG4TextPlus? new G4TextP 144 fpG4TextPlus = rhs.fpG4TextPlus? new G4TextPlus(*rhs.fpG4TextPlus): 0; 143 fMarkerOrPolyline = rhs.fMarkerOrPolyline; 145 fMarkerOrPolyline = rhs.fMarkerOrPolyline; 144 return *this; 146 return *this; 145 } 147 } 146 148 147 G4OpenGLStoredSceneHandler::G4OpenGLStoredScen 149 G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler 148 (G4VGraphicsSystem& system, 150 (G4VGraphicsSystem& system, 149 const G4String& name): 151 const G4String& name): 150 G4OpenGLSceneHandler (system, fSceneIdCount++, 152 G4OpenGLSceneHandler (system, fSceneIdCount++, name), 151 fDoNotUseDisplayList(false), << 152 fTopPODL (0) 153 fTopPODL (0) 153 {} 154 {} 154 155 155 G4OpenGLStoredSceneHandler::~G4OpenGLStoredSce 156 G4OpenGLStoredSceneHandler::~G4OpenGLStoredSceneHandler () 156 {} 157 {} 157 158 158 void G4OpenGLStoredSceneHandler::BeginPrimitiv 159 void G4OpenGLStoredSceneHandler::BeginPrimitives 159 (const G4Transform3D& objectTransformation) 160 (const G4Transform3D& objectTransformation) 160 { 161 { 161 G4OpenGLSceneHandler::BeginPrimitives (objec 162 G4OpenGLSceneHandler::BeginPrimitives (objectTransformation); 162 if (fReadyForTransients) glDrawBuffer (GL_FR 163 if (fReadyForTransients) glDrawBuffer (GL_FRONT); 163 // Display list setup moved to AddPrimitiveP 164 // Display list setup moved to AddPrimitivePreamble. See notes there. 164 } 165 } 165 166 166 void G4OpenGLStoredSceneHandler::EndPrimitives 167 void G4OpenGLStoredSceneHandler::EndPrimitives () 167 { 168 { 168 // See all primitives immediately... At lea 169 // See all primitives immediately... At least soon... 169 ScaledFlush(); 170 ScaledFlush(); 170 glDrawBuffer (GL_BACK); 171 glDrawBuffer (GL_BACK); 171 G4OpenGLSceneHandler::EndPrimitives (); 172 G4OpenGLSceneHandler::EndPrimitives (); 172 } 173 } 173 174 174 void G4OpenGLStoredSceneHandler::BeginPrimitiv 175 void G4OpenGLStoredSceneHandler::BeginPrimitives2D 175 (const G4Transform3D& objectTransformation) 176 (const G4Transform3D& objectTransformation) 176 { 177 { 177 G4OpenGLSceneHandler::BeginPrimitives2D(obje 178 G4OpenGLSceneHandler::BeginPrimitives2D(objectTransformation); 178 if (fReadyForTransients) glDrawBuffer (GL_FR 179 if (fReadyForTransients) glDrawBuffer (GL_FRONT); 179 } 180 } 180 181 181 void G4OpenGLStoredSceneHandler::EndPrimitives 182 void G4OpenGLStoredSceneHandler::EndPrimitives2D () 182 { 183 { 183 // See all primitives immediately... At lea 184 // See all primitives immediately... At least soon... 184 ScaledFlush(); 185 ScaledFlush(); 185 glDrawBuffer (GL_BACK); 186 glDrawBuffer (GL_BACK); 186 G4OpenGLSceneHandler::EndPrimitives2D (); 187 G4OpenGLSceneHandler::EndPrimitives2D (); 187 } 188 } 188 189 189 G4bool G4OpenGLStoredSceneHandler::AddPrimitiv 190 G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4VMarker& visible) 190 { 191 { 191 return AddPrimitivePreambleInternal(visible, 192 return AddPrimitivePreambleInternal(visible, true, false); 192 } 193 } 193 G4bool G4OpenGLStoredSceneHandler::AddPrimitiv 194 G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Polyline& visible) 194 { 195 { 195 return AddPrimitivePreambleInternal(visible, 196 return AddPrimitivePreambleInternal(visible, false, true); 196 } 197 } 197 G4bool G4OpenGLStoredSceneHandler::AddPrimitiv 198 G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Polyhedron& visible) 198 { 199 { 199 return AddPrimitivePreambleInternal(visible, 200 return AddPrimitivePreambleInternal(visible, false, false); 200 } 201 } 201 202 202 G4bool G4OpenGLStoredSceneHandler::AddPrimitiv 203 G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreambleInternal 203 (const G4Visible& visible, bool isMarker, bool 204 (const G4Visible& visible, bool isMarker, bool isPolyline) 204 { 205 { 205 // Get applicable vis attributes for all primi 206 // Get applicable vis attributes for all primitives. 206 fpVisAttribs = fpViewer->GetApplicableVisAtt 207 fpVisAttribs = fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes()); 207 const G4Colour& c = GetColour (); 208 const G4Colour& c = GetColour (); 208 G4double opacity = c.GetAlpha (); 209 G4double opacity = c.GetAlpha (); 209 210 210 G4bool transparency_enabled = true; 211 G4bool transparency_enabled = true; 211 G4bool isMarkerNotHidden = true; 212 G4bool isMarkerNotHidden = true; 212 G4OpenGLViewer* pOGLViewer = dynamic_cast<G4 213 G4OpenGLViewer* pOGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer); 213 if (pOGLViewer) { 214 if (pOGLViewer) { 214 transparency_enabled = pOGLViewer->transpa 215 transparency_enabled = pOGLViewer->transparency_enabled; 215 isMarkerNotHidden = pOGLViewer->fVP.IsMark 216 isMarkerNotHidden = pOGLViewer->fVP.IsMarkerNotHidden(); 216 } 217 } 217 218 218 G4bool isTransparent = opacity < 1.; 219 G4bool isTransparent = opacity < 1.; 219 G4bool isMarkerOrPolyline = isMarker || isPo 220 G4bool isMarkerOrPolyline = isMarker || isPolyline; 220 G4bool treatAsTransparent = transparency_ena 221 G4bool treatAsTransparent = transparency_enabled && isTransparent; 221 G4bool treatAsNotHidden = isMarkerNotHidden 222 G4bool treatAsNotHidden = isMarkerNotHidden && isMarkerOrPolyline; 222 223 223 if (fProcessing2D) glDisable (GL_DEPTH_TEST) 224 if (fProcessing2D) glDisable (GL_DEPTH_TEST); 224 else { 225 else { 225 if (isMarkerOrPolyline && isMarkerNotHidde 226 if (isMarkerOrPolyline && isMarkerNotHidden) 226 glDisable (GL_DEPTH_TEST); 227 glDisable (GL_DEPTH_TEST); 227 else {glEnable (GL_DEPTH_TEST); glDepthFun 228 else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);} 228 } 229 } 229 230 230 if (fThreePassCapable) { 231 if (fThreePassCapable) { 231 232 232 // Ensure transparent objects are drawn *a << 233 // Ensure transparent objects are drawn opaque ones and before 233 // non-hidden markers. The problem of ble 234 // non-hidden markers. The problem of blending/transparency/alpha 234 // is quite a tricky one - see History of 235 // is quite a tricky one - see History of opengl-V07-01-01/2/3. 235 if (!(fSecondPassForTransparency || fThird 236 if (!(fSecondPassForTransparency || fThirdPassForNonHiddenMarkers)) { 236 // First pass... 237 // First pass... 237 if (treatAsTransparent) { // Request pa 238 if (treatAsTransparent) { // Request pass for transparent objects... 238 fSecondPassForTransparencyRequested = 239 fSecondPassForTransparencyRequested = true; 239 } 240 } 240 if (treatAsNotHidden) { // Request pa 241 if (treatAsNotHidden) { // Request pass for non-hidden markers... 241 fThirdPassForNonHiddenMarkersRequested 242 fThirdPassForNonHiddenMarkersRequested = true; 242 } 243 } 243 // On first pass, transparent objects an 244 // On first pass, transparent objects and non-hidden markers are not drawn... 244 if (treatAsTransparent || treatAsNotHidd 245 if (treatAsTransparent || treatAsNotHidden) { 245 return false; // No further processin 246 return false; // No further processing. 246 } 247 } 247 } 248 } 248 249 249 // On second pass, only transparent object 250 // On second pass, only transparent objects are drawn... 250 if (fSecondPassForTransparency) { 251 if (fSecondPassForTransparency) { 251 if (!treatAsTransparent) { 252 if (!treatAsTransparent) { 252 return false; // No further processin 253 return false; // No further processing. 253 } 254 } 254 } 255 } 255 256 256 // On third pass, only non-hidden markers 257 // On third pass, only non-hidden markers are drawn... 257 if (fThirdPassForNonHiddenMarkers) { 258 if (fThirdPassForNonHiddenMarkers) { 258 if (!treatAsNotHidden) { 259 if (!treatAsNotHidden) { 259 return false; // No further processin 260 return false; // No further processing. 260 } 261 } 261 } 262 } 262 } // fThreePassCapable 263 } // fThreePassCapable 263 264 264 // Loads G4Atts for picking... 265 // Loads G4Atts for picking... 265 G4bool isPicking = false; 266 G4bool isPicking = false; 266 if (fpViewer->GetViewParameters().IsPicking( 267 if (fpViewer->GetViewParameters().IsPicking()) { 267 isPicking = true; 268 isPicking = true; 268 glLoadName(++fPickName); 269 glLoadName(++fPickName); 269 G4AttHolder* holder = new G4AttHolder; 270 G4AttHolder* holder = new G4AttHolder; 270 LoadAtts(visible, holder); 271 LoadAtts(visible, holder); 271 fPickMap[fPickName] = holder; 272 fPickMap[fPickName] = holder; 272 } 273 } >> 274 >> 275 const G4VSolid* pSolid = 0; >> 276 >> 277 // Can we re-use a display list? >> 278 if (isMarker) >> 279 // It is a marker, which may have its own position relative to fObjectTransformation >> 280 goto end_of_display_list_reuse_test; >> 281 if (fpViewer->GetViewParameters().GetVisAttributesModifiers().size()) >> 282 // Touchables have been modified - don't risk re-using display list. >> 283 goto end_of_display_list_reuse_test; >> 284 { // It is a viable candidate for display list re-use >> 285 G4PhysicalVolumeModel* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel); >> 286 if (pPVModel) { >> 287 // Check that it isn't a G4LogicalVolumeModel (which is a sub-class of >> 288 // G4PhysicalVolumeModel). >> 289 G4LogicalVolumeModel* pLVModel = >> 290 dynamic_cast<G4LogicalVolumeModel*>(pPVModel); >> 291 if (pLVModel) >> 292 // Logical volume model - don't re-use. >> 293 goto end_of_display_list_reuse_test; >> 294 // If part of the geometry hierarchy, i.e., from a >> 295 // G4PhysicalVolumeModel, check if a display list already exists for >> 296 // this solid, re-use it if possible. We could be smarter, and >> 297 // recognise repeated branches of the geometry hierarchy, for >> 298 // example. But this algorithm should be secure, I think... >> 299 G4VPhysicalVolume* pPV = pPVModel->GetCurrentPV(); >> 300 if (!pPV) >> 301 // It's probably a dummy model, e.g., for a user-drawn hit? >> 302 goto end_of_display_list_reuse_test; >> 303 G4LogicalVolume* pLV = pPV->GetLogicalVolume(); >> 304 if (!pLV) >> 305 // Dummy model again? >> 306 goto end_of_display_list_reuse_test; >> 307 pSolid = pLV->GetSolid(); >> 308 EAxis axis = kRho; >> 309 G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV(); >> 310 if (pCurrentPV -> IsReplicated ()) { >> 311 G4int nReplicas; >> 312 G4double width; >> 313 G4double offset; >> 314 G4bool consuming; >> 315 pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming); >> 316 } >> 317 // Provided it is not parametrised (because if so, the >> 318 // solid's parameters might have been changed)... >> 319 if (!(pCurrentPV -> IsParameterised ()) && >> 320 // Provided it is not replicated radially (because if so, the >> 321 // solid's parameters will have been changed)... >> 322 !(pCurrentPV -> IsReplicated () && axis == kRho) && >> 323 // ...and if the solid has already been rendered... >> 324 (fSolidMap.find (pSolid) != fSolidMap.end ())) { >> 325 fDisplayListId = fSolidMap [pSolid]; >> 326 PO po(fDisplayListId,fObjectTransformation); >> 327 if (isPicking) po.fPickName = fPickName; >> 328 po.fColour = c; >> 329 po.fMarkerOrPolyline = isMarkerOrPolyline; >> 330 fPOList.push_back(po); >> 331 // No need to test if gl commands are used (result of >> 332 // ExtraPOProcessing) because we have already decided they will >> 333 // not, at least not here. Also, pass a dummy G4Visible since >> 334 // not relevant for G4PhysicalVolumeModel. >> 335 (void) ExtraPOProcessing(G4Visible(), fPOList.size() - 1); >> 336 return false; // No further processing. >> 337 } >> 338 } >> 339 } >> 340 end_of_display_list_reuse_test: 273 341 274 // Because of our need to control colour of 342 // Because of our need to control colour of transients (display by 275 // time fading), display lists may only cove 343 // time fading), display lists may only cover a single primitive. 276 // So display list setup is here. 344 // So display list setup is here. 277 << 345 278 if (fDoNotUseDisplayList) { << 346 if (fMemoryForDisplayLists) { 279 << 280 glPushMatrix(); << 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 << 289 } else { << 290 << 291 fDisplayListId = glGenLists (1); 347 fDisplayListId = glGenLists (1); 292 if (glGetError() == GL_OUT_OF_MEMORY) { << 348 if (glGetError() == GL_OUT_OF_MEMORY || 293 static G4int errorCount = 0; << 349 fDisplayListId > fDisplayListLimit) { 294 if (errorCount < 5) { << 350 G4cout << 295 errorCount++; << 351 "********************* WARNING! ********************" 296 G4ExceptionDescription ed; << 352 "\n* Display list limit reached in OpenGL." 297 ed << << 353 "\n* Continuing drawing WITHOUT STORING. Scene only partially refreshable." 298 "Error attempting to create an OpenGL << 354 "\n* Current limit: " << fDisplayListLimit << " primitives" 299 "\nCurrent display list id: " << fDisp << 355 ". Change with \"/vis/ogl/set/displayListLimit\"." 300 "\nMaybe out of memory?"; << 356 "\n***************************************************" 301 G4Exception << 357 << G4endl; 302 ("G4OpenGLStoredSceneHandler::AddPrimi << 358 fMemoryForDisplayLists = false; 303 JustWarning,ed); << 304 } << 305 return false; << 306 } 359 } >> 360 } >> 361 >> 362 if (pSolid) fSolidMap [pSolid] = fDisplayListId; >> 363 >> 364 if (fMemoryForDisplayLists) { 307 if (fReadyForTransients) { 365 if (fReadyForTransients) { 308 TO to(fDisplayListId, fObjectTransformat 366 TO to(fDisplayListId, fObjectTransformation); 309 if (isPicking) to.fPickName = fPickName; 367 if (isPicking) to.fPickName = fPickName; 310 to.fColour = c; 368 to.fColour = c; 311 to.fStartTime = fpVisAttribs->GetStartTi 369 to.fStartTime = fpVisAttribs->GetStartTime(); 312 to.fEndTime = fpVisAttribs->GetEndTime() 370 to.fEndTime = fpVisAttribs->GetEndTime(); 313 to.fMarkerOrPolyline = isMarkerOrPolylin 371 to.fMarkerOrPolyline = isMarkerOrPolyline; 314 fTOList.push_back(to); 372 fTOList.push_back(to); 315 // For transient objects, colour, transf 373 // For transient objects, colour, transformation, are kept in 316 // the TO, so should *not* be in the dis 374 // the TO, so should *not* be in the display list. As mentioned 317 // above, in some cases (display-by-time 375 // above, in some cases (display-by-time fading) we need to have 318 // independent control of colour. But f 376 // independent control of colour. But for now transform and set 319 // colour for immediate display. 377 // colour for immediate display. 320 glPushMatrix(); 378 glPushMatrix(); 321 G4OpenGLTransform3D oglt (fObjectTransfo 379 G4OpenGLTransform3D oglt (fObjectTransformation); 322 glMultMatrixd (oglt.GetGLMatrix ()); 380 glMultMatrixd (oglt.GetGLMatrix ()); 323 if (transparency_enabled) { 381 if (transparency_enabled) { 324 glColor4d(c.GetRed(),c.GetGreen(),c.Ge 382 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha()); 325 } else { 383 } else { 326 glColor3d(c.GetRed(),c.GetGreen(),c.Ge 384 glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue()); 327 } 385 } 328 (void) ExtraTOProcessing(visible, fTOLis 386 (void) ExtraTOProcessing(visible, fTOList.size() - 1); 329 // Ignore return value of the above. If 387 // Ignore return value of the above. If this visible does not use 330 // gl commands, a display list is create 388 // gl commands, a display list is created that is empty and not 331 // used. 389 // used. 332 glNewList (fDisplayListId, GL_COMPILE_AN 390 glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE); 333 } else { 391 } else { 334 PO po(fDisplayListId, fObjectTransformat 392 PO po(fDisplayListId, fObjectTransformation); 335 if (isPicking) po.fPickName = fPickName; 393 if (isPicking) po.fPickName = fPickName; 336 po.fColour = c; 394 po.fColour = c; 337 po.fMarkerOrPolyline = isMarkerOrPolylin 395 po.fMarkerOrPolyline = isMarkerOrPolyline; 338 fPOList.push_back(po); 396 fPOList.push_back(po); 339 // For permanent objects, colour is kept 397 // For permanent objects, colour is kept in the PO, so should 340 // *not* be in the display list. This i 398 // *not* be in the display list. This is so that sub-classes 341 // may implement colour modifications ac 399 // may implement colour modifications according to their own 342 // criteria, e.g., scene tree slider in 400 // criteria, e.g., scene tree slider in Qt. But for now set 343 // colour for immediate display. 401 // colour for immediate display. 344 if (transparency_enabled) { 402 if (transparency_enabled) { 345 glColor4d(c.GetRed(),c.GetGreen(),c.Ge 403 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha()); 346 } else { 404 } else { 347 glColor3d(c.GetRed(),c.GetGreen(),c.Ge 405 glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue()); 348 } 406 } 349 G4bool usesGLCommands = ExtraPOProcessin 407 G4bool usesGLCommands = ExtraPOProcessing(visible, fPOList.size() - 1); 350 // Transients are displayed as they come 408 // Transients are displayed as they come (GL_COMPILE_AND_EXECUTE 351 // above) but persistents are compiled i 409 // above) but persistents are compiled into display lists 352 // (GL_COMPILE only) and then drawn from 410 // (GL_COMPILE only) and then drawn from the display lists with 353 // their fObjectTransformation as stored 411 // their fObjectTransformation as stored in fPOList. Thus, 354 // there is no need to do glMultMatrixd 412 // there is no need to do glMultMatrixd here. If 355 // ExtraPOProcessing says the visible ob 413 // ExtraPOProcessing says the visible object does not use gl 356 // commands, simply return and abandon f 414 // commands, simply return and abandon further processing. It 357 // is assumed that all relevant informat 415 // is assumed that all relevant information is kept in the 358 // POList. 416 // POList. 359 if (!usesGLCommands) return false; 417 if (!usesGLCommands) return false; 360 glNewList (fDisplayListId, GL_COMPILE); 418 glNewList (fDisplayListId, GL_COMPILE); 361 } 419 } >> 420 } else { // Out of memory (or being used when display lists not required). >> 421 glPushMatrix(); >> 422 G4OpenGLTransform3D oglt (fObjectTransformation); >> 423 glMultMatrixd (oglt.GetGLMatrix ()); >> 424 if (transparency_enabled) { >> 425 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha()); >> 426 } else { >> 427 glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue()); >> 428 } 362 } 429 } 363 430 364 if (fProcessing2D) { 431 if (fProcessing2D) { 365 // Push current 3D world matrices and load 432 // Push current 3D world matrices and load identity to define screen 366 // coordinates... 433 // coordinates... 367 glMatrixMode (GL_PROJECTION); 434 glMatrixMode (GL_PROJECTION); 368 glPushMatrix(); 435 glPushMatrix(); 369 glLoadIdentity(); 436 glLoadIdentity(); 370 if (pOGLViewer) { 437 if (pOGLViewer) { 371 pOGLViewer->g4GlOrtho (-1., 1., -1., 1., 438 pOGLViewer->g4GlOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG); 372 } 439 } 373 glMatrixMode (GL_MODELVIEW); 440 glMatrixMode (GL_MODELVIEW); 374 glPushMatrix(); 441 glPushMatrix(); 375 glLoadIdentity(); 442 glLoadIdentity(); 376 G4OpenGLTransform3D oglt (fObjectTransform 443 G4OpenGLTransform3D oglt (fObjectTransformation); 377 glMultMatrixd (oglt.GetGLMatrix ()); 444 glMultMatrixd (oglt.GetGLMatrix ()); 378 glDisable (GL_LIGHTING); 445 glDisable (GL_LIGHTING); 379 } else { 446 } else { 380 if (isMarker) { 447 if (isMarker) { 381 glDisable (GL_LIGHTING); 448 glDisable (GL_LIGHTING); 382 } else { 449 } else { 383 glEnable (GL_LIGHTING); 450 glEnable (GL_LIGHTING); 384 } 451 } 385 } 452 } 386 453 387 return true; 454 return true; 388 } 455 } 389 456 390 void G4OpenGLStoredSceneHandler::AddPrimitiveP 457 void G4OpenGLStoredSceneHandler::AddPrimitivePostamble() 391 { 458 { 392 if (fProcessing2D) { 459 if (fProcessing2D) { 393 // Pop current 3D world matrices back agai 460 // Pop current 3D world matrices back again... 394 glMatrixMode (GL_PROJECTION); 461 glMatrixMode (GL_PROJECTION); 395 glPopMatrix(); 462 glPopMatrix(); 396 glMatrixMode (GL_MODELVIEW); 463 glMatrixMode (GL_MODELVIEW); 397 glPopMatrix(); 464 glPopMatrix(); 398 } 465 } 399 466 400 // if ((glGetError() == GL_TABLE_TOO_LARGE) 467 // if ((glGetError() == GL_TABLE_TOO_LARGE) || (glGetError() == GL_OUT_OF_MEMORY)) { // Could close? 401 if (glGetError() == GL_OUT_OF_MEMORY) { // 468 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close? 402 G4cerr << 469 G4cerr << 403 "ERROR: G4OpenGLStoredSceneHandler::AddP 470 "ERROR: G4OpenGLStoredSceneHandler::AddPrimitivePostamble: Failure" 404 " to allocate display List for fTopPODL 471 " to allocate display List for fTopPODL - try OpenGL Immediated mode." 405 << G4endl; 472 << G4endl; 406 } 473 } 407 if (!fDoNotUseDisplayList) { << 474 if (fMemoryForDisplayLists) { 408 glEndList(); 475 glEndList(); 409 if (glGetError() == GL_OUT_OF_MEMORY) { / 476 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close? 410 G4cerr << 477 G4cerr << 411 "ERROR: G4OpenGLStoredSceneHandler::Ad 478 "ERROR: G4OpenGLStoredSceneHandler::AddPrimitivePostamble: Failure" 412 " to allocate display List for fTopPODL - t 479 " to allocate display List for fTopPODL - try OpenGL Immediated mode." 413 << G4endl; 480 << G4endl; 414 } 481 } 415 } 482 } 416 if (fReadyForTransients || fDoNotUseDisplayL << 483 if (fReadyForTransients || !fMemoryForDisplayLists) { 417 glPopMatrix(); 484 glPopMatrix(); 418 } 485 } 419 } 486 } 420 487 421 void G4OpenGLStoredSceneHandler::AddPrimitive 488 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline) 422 { 489 { 423 G4bool furtherprocessing = AddPrimitivePream 490 G4bool furtherprocessing = AddPrimitivePreamble(polyline); 424 if (furtherprocessing) { 491 if (furtherprocessing) { 425 G4OpenGLSceneHandler::AddPrimitive(polylin 492 G4OpenGLSceneHandler::AddPrimitive(polyline); 426 AddPrimitivePostamble(); 493 AddPrimitivePostamble(); 427 } 494 } 428 } 495 } 429 496 430 void G4OpenGLStoredSceneHandler::AddPrimitive 497 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker) 431 { 498 { 432 G4bool furtherprocessing = AddPrimitivePream 499 G4bool furtherprocessing = AddPrimitivePreamble(polymarker); 433 if (furtherprocessing) { 500 if (furtherprocessing) { 434 G4OpenGLSceneHandler::AddPrimitive(polymar 501 G4OpenGLSceneHandler::AddPrimitive(polymarker); 435 AddPrimitivePostamble(); 502 AddPrimitivePostamble(); 436 } 503 } 437 } 504 } 438 505 439 void G4OpenGLStoredSceneHandler::AddPrimitive 506 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Text& text) 440 { 507 { 441 // Note: colour is still handled in 508 // Note: colour is still handled in 442 // G4OpenGLSceneHandler::AddPrimitive(const 509 // G4OpenGLSceneHandler::AddPrimitive(const G4Text&), so it still 443 // gets into the display list 510 // gets into the display list 444 G4bool furtherprocessing = AddPrimitivePream 511 G4bool furtherprocessing = AddPrimitivePreamble(text); 445 if (furtherprocessing) { 512 if (furtherprocessing) { 446 G4OpenGLSceneHandler::AddPrimitive(text); 513 G4OpenGLSceneHandler::AddPrimitive(text); 447 AddPrimitivePostamble(); 514 AddPrimitivePostamble(); 448 } 515 } 449 } 516 } 450 517 451 void G4OpenGLStoredSceneHandler::AddPrimitive 518 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle) 452 { 519 { 453 G4bool furtherprocessing = AddPrimitivePream 520 G4bool furtherprocessing = AddPrimitivePreamble(circle); 454 if (furtherprocessing) { 521 if (furtherprocessing) { 455 G4OpenGLSceneHandler::AddPrimitive(circle) 522 G4OpenGLSceneHandler::AddPrimitive(circle); 456 AddPrimitivePostamble(); 523 AddPrimitivePostamble(); 457 } 524 } 458 } 525 } 459 526 460 void G4OpenGLStoredSceneHandler::AddPrimitive 527 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square) 461 { 528 { 462 G4bool furtherprocessing = AddPrimitivePream 529 G4bool furtherprocessing = AddPrimitivePreamble(square); 463 if (furtherprocessing) { 530 if (furtherprocessing) { 464 G4OpenGLSceneHandler::AddPrimitive(square) 531 G4OpenGLSceneHandler::AddPrimitive(square); 465 AddPrimitivePostamble(); 532 AddPrimitivePostamble(); 466 } 533 } 467 } 534 } 468 535 469 void G4OpenGLStoredSceneHandler::AddPrimitive 536 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) 470 { 537 { 471 // Note: colour is still handled in 538 // Note: colour is still handled in 472 // G4OpenGLSceneHandler::AddPrimitive(const 539 // G4OpenGLSceneHandler::AddPrimitive(const G4Polyhedron&), so it still 473 // gets into the display list 540 // gets into the display list 474 G4bool furtherprocessing = AddPrimitivePream 541 G4bool furtherprocessing = AddPrimitivePreamble(polyhedron); 475 if (furtherprocessing) { 542 if (furtherprocessing) { 476 G4OpenGLSceneHandler::AddPrimitive(polyhed 543 G4OpenGLSceneHandler::AddPrimitive(polyhedron); 477 AddPrimitivePostamble(); 544 AddPrimitivePostamble(); 478 } 545 } 479 } 546 } 480 547 481 void G4OpenGLStoredSceneHandler::BeginModeling 548 void G4OpenGLStoredSceneHandler::BeginModeling () { 482 G4VSceneHandler::BeginModeling(); 549 G4VSceneHandler::BeginModeling(); 483 /* Debug... 550 /* Debug... 484 fDisplayListId = glGenLists (1); 551 fDisplayListId = glGenLists (1); 485 G4cout << "OGL::fDisplayListId (start): " << 552 G4cout << "OGL::fDisplayListId (start): " << fDisplayListId << G4endl; 486 */ 553 */ 487 } 554 } 488 555 489 void G4OpenGLStoredSceneHandler::EndModeling ( 556 void G4OpenGLStoredSceneHandler::EndModeling () { 490 // Make a List which calls the other lists. 557 // Make a List which calls the other lists. 491 fTopPODL = glGenLists (1); 558 fTopPODL = glGenLists (1); 492 if (glGetError() == GL_OUT_OF_MEMORY) { // 559 if (glGetError() == GL_OUT_OF_MEMORY) { // Could pre-allocate? 493 G4cerr << 560 G4cerr << 494 "ERROR: G4OpenGLStoredSceneHandler::EndM 561 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate" 495 " display List for fTopPODL - try OpenG 562 " display List for fTopPODL - try OpenGL Immediated mode." 496 << G4endl; 563 << G4endl; 497 } else { 564 } else { 498 565 499 glNewList (fTopPODL, GL_COMPILE); { 566 glNewList (fTopPODL, GL_COMPILE); { 500 for (size_t i = 0; i < fPOList.size (); 567 for (size_t i = 0; i < fPOList.size (); i++) { 501 glPushMatrix(); 568 glPushMatrix(); 502 G4OpenGLTransform3D oglt (fPOList[i].fTransf 569 G4OpenGLTransform3D oglt (fPOList[i].fTransform); 503 glMultMatrixd (oglt.GetGLMatrix ()); 570 glMultMatrixd (oglt.GetGLMatrix ()); 504 if (fpViewer->GetViewParameters().IsPicking( 571 if (fpViewer->GetViewParameters().IsPicking()) 505 glLoadName(fPOList[i].fPickName); 572 glLoadName(fPOList[i].fPickName); 506 glCallList (fPOList[i].fDisplayListId); 573 glCallList (fPOList[i].fDisplayListId); 507 glPopMatrix(); 574 glPopMatrix(); 508 } 575 } 509 } 576 } 510 glEndList (); 577 glEndList (); 511 578 512 if (glGetError() == GL_OUT_OF_MEMORY) { / 579 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close? 513 G4cerr << 580 G4cerr << 514 "ERROR: G4OpenGLStoredSceneHandler::En 581 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate" 515 " display List for fTopPODL - try Ope 582 " display List for fTopPODL - try OpenGL Immediated mode." 516 << G4endl; 583 << G4endl; 517 } 584 } 518 } 585 } 519 586 520 G4VSceneHandler::EndModeling (); 587 G4VSceneHandler::EndModeling (); 521 } 588 } 522 589 523 void G4OpenGLStoredSceneHandler::ClearStore () 590 void G4OpenGLStoredSceneHandler::ClearStore () { 524 591 525 //G4cout << "G4OpenGLStoredSceneHandler::Cle 592 //G4cout << "G4OpenGLStoredSceneHandler::ClearStore" << G4endl; 526 593 527 G4VSceneHandler::ClearStore (); // Sets nee 594 G4VSceneHandler::ClearStore (); // Sets need kernel visit, etc. 528 595 529 // Delete OpenGL permanent display lists. 596 // Delete OpenGL permanent display lists. 530 for (size_t i = 0; i < fPOList.size (); i++) 597 for (size_t i = 0; i < fPOList.size (); i++) 531 glDeleteLists (fPOList[i].fDisplayListId, 598 glDeleteLists (fPOList[i].fDisplayListId, 1); 532 if (fTopPODL) glDeleteLists (fTopPODL, 1); 599 if (fTopPODL) glDeleteLists (fTopPODL, 1); 533 fTopPODL = 0; 600 fTopPODL = 0; 534 601 535 // Clear other lists, dictionary, etc. 602 // Clear other lists, dictionary, etc. 536 fPOList.clear (); 603 fPOList.clear (); 537 fSolidMap.clear (); 604 fSolidMap.clear (); 538 ClearAndDestroyAtts(); 605 ClearAndDestroyAtts(); 539 606 540 // ...and clear transient store... 607 // ...and clear transient store... 541 for (size_t i = 0; i < fTOList.size (); i++) 608 for (size_t i = 0; i < fTOList.size (); i++) 542 glDeleteLists(fTOList[i].fDisplayListId, 1 609 glDeleteLists(fTOList[i].fDisplayListId, 1); 543 fTOList.clear (); 610 fTOList.clear (); >> 611 >> 612 fMemoryForDisplayLists = true; 544 } 613 } 545 614 546 void G4OpenGLStoredSceneHandler::ClearTransien 615 void G4OpenGLStoredSceneHandler::ClearTransientStore () 547 { 616 { 548 //G4cout << "G4OpenGLStoredSceneHandler::Cle 617 //G4cout << "G4OpenGLStoredSceneHandler::ClearTransientStore" << G4endl; 549 618 550 // Delete OpenGL transient display lists and 619 // Delete OpenGL transient display lists and Transient Objects themselves. 551 for (size_t i = 0; i < fTOList.size (); i++) 620 for (size_t i = 0; i < fTOList.size (); i++) 552 glDeleteLists(fTOList[i].fDisplayListId, 1 621 glDeleteLists(fTOList[i].fDisplayListId, 1); 553 fTOList.clear (); 622 fTOList.clear (); >> 623 >> 624 fMemoryForDisplayLists = true; 554 625 555 // Redraw the scene ready for the next event 626 // Redraw the scene ready for the next event. 556 if (fpViewer) { 627 if (fpViewer) { 557 fpViewer -> SetView (); 628 fpViewer -> SetView (); 558 fpViewer -> ClearView (); 629 fpViewer -> ClearView (); 559 fpViewer -> DrawView (); 630 fpViewer -> DrawView (); 560 } 631 } 561 } 632 } 562 633