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