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