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