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 27th March 1996 29 // Andrew Walkden 27th March 1996 30 // OpenGL stored scene - creates OpenGL displa 30 // OpenGL stored scene - creates OpenGL display lists. 31 // OpenGL immediate scene - draws immediately 31 // OpenGL immediate scene - draws immediately to buffer 32 // (saving space on 32 // (saving space on server). 33 33 >> 34 #ifdef G4VIS_BUILD_OPENGL_DRIVER 34 35 35 # include "G4OpenGLSceneHandler.hh" 36 # include "G4OpenGLSceneHandler.hh" 36 # include "G4OpenGLViewer.hh" 37 # include "G4OpenGLViewer.hh" 37 # include "G4OpenGLTransform3D.hh" 38 # include "G4OpenGLTransform3D.hh" 38 # include "G4Point3D.hh" 39 # include "G4Point3D.hh" 39 # include "G4Normal3D.hh" 40 # include "G4Normal3D.hh" 40 # include "G4Transform3D.hh" 41 # include "G4Transform3D.hh" 41 # include "G4Polyline.hh" 42 # include "G4Polyline.hh" 42 # include "G4Polymarker.hh" 43 # include "G4Polymarker.hh" 43 # include "G4Text.hh" 44 # include "G4Text.hh" 44 # include "G4Circle.hh" 45 # include "G4Circle.hh" 45 # include "G4Square.hh" 46 # include "G4Square.hh" 46 # include "G4VMarker.hh" 47 # include "G4VMarker.hh" 47 # include "G4Polyhedron.hh" 48 # include "G4Polyhedron.hh" 48 # include "G4VisAttributes.hh" 49 # include "G4VisAttributes.hh" 49 # include "G4PhysicalVolumeModel.hh" 50 # include "G4PhysicalVolumeModel.hh" 50 # include "G4VPhysicalVolume.hh" 51 # include "G4VPhysicalVolume.hh" 51 # include "G4LogicalVolume.hh" 52 # include "G4LogicalVolume.hh" 52 # include "G4VSolid.hh" 53 # include "G4VSolid.hh" 53 # include "G4Scene.hh" 54 # include "G4Scene.hh" 54 # include "G4VisExtent.hh" 55 # include "G4VisExtent.hh" 55 # include "G4AttHolder.hh" 56 # include "G4AttHolder.hh" 56 # include "G4PhysicalConstants.hh" 57 # include "G4PhysicalConstants.hh" 57 # include "G4RunManager.hh" 58 # include "G4RunManager.hh" 58 # include "G4Run.hh" 59 # include "G4Run.hh" 59 # include "G4RunManagerFactory.hh" 60 # include "G4RunManagerFactory.hh" 60 # include "G4Mesh.hh" << 61 # include "G4PseudoScene.hh" << 62 # include "G4VisManager.hh" << 63 61 64 const GLubyte G4OpenGLSceneHandler::fStippleMa 62 const GLubyte G4OpenGLSceneHandler::fStippleMaskHashed [128] = { 65 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 63 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 66 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 64 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 67 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 65 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 68 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 66 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 69 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 67 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 70 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 68 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 71 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 69 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 72 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 70 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 73 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 71 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 74 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 72 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 75 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 73 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 76 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 74 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 77 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 75 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 78 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 76 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 79 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 77 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 80 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55 78 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55 81 }; 79 }; 82 80 83 G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4 81 G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4VGraphicsSystem& system, 84 G4 82 G4int id, 85 co 83 const G4String& name): 86 G4VSceneHandler (system, id, name), 84 G4VSceneHandler (system, id, name), >> 85 #ifdef G4OPENGL_VERSION_2 >> 86 fEmulate_GL_QUADS(false), >> 87 #endif 87 fPickName(0), 88 fPickName(0), 88 fThreePassCapable(false), 89 fThreePassCapable(false), 89 fSecondPassForTransparencyRequested(false), 90 fSecondPassForTransparencyRequested(false), 90 fSecondPassForTransparency(false), 91 fSecondPassForTransparency(false), 91 fThirdPassForNonHiddenMarkersRequested(false), 92 fThirdPassForNonHiddenMarkersRequested(false), 92 fThirdPassForNonHiddenMarkers(false), 93 fThirdPassForNonHiddenMarkers(false), 93 fEdgeFlag(true) 94 fEdgeFlag(true) 94 { 95 { 95 } 96 } 96 97 97 G4OpenGLSceneHandler::~G4OpenGLSceneHandler () 98 G4OpenGLSceneHandler::~G4OpenGLSceneHandler () 98 { 99 { 99 ClearStore (); 100 ClearStore (); 100 } 101 } 101 102 102 void G4OpenGLSceneHandler::ClearAndDestroyAtts 103 void G4OpenGLSceneHandler::ClearAndDestroyAtts() 103 { 104 { 104 std::map<GLuint, G4AttHolder*>::iterator i; 105 std::map<GLuint, G4AttHolder*>::iterator i; 105 for (i = fPickMap.begin(); i != fPickMap.end 106 for (i = fPickMap.begin(); i != fPickMap.end(); ++i) delete i->second; 106 fPickMap.clear(); 107 fPickMap.clear(); 107 } 108 } 108 109 109 G4int G4OpenGLSceneHandler::fEntitiesFlushInte 110 G4int G4OpenGLSceneHandler::fEntitiesFlushInterval = 100; 110 G4OpenGLSceneHandler::FlushAction 111 G4OpenGLSceneHandler::FlushAction 111 G4OpenGLSceneHandler::fFlushAction = G4OpenGLS 112 G4OpenGLSceneHandler::fFlushAction = G4OpenGLSceneHandler::NthEvent; 112 113 113 void G4OpenGLSceneHandler::ScaledFlush() 114 void G4OpenGLSceneHandler::ScaledFlush() 114 { 115 { 115 if (fReadyForTransients) { 116 if (fReadyForTransients) { 116 117 117 // Drawing transients, e.g., trajectories. 118 // Drawing transients, e.g., trajectories. 118 119 119 if (!fpScene) { 120 if (!fpScene) { 120 // No scene - shouldn't happen 121 // No scene - shouldn't happen 121 glFlush(); 122 glFlush(); 122 return; 123 return; 123 } 124 } 124 // Get event from modeling parameters 125 // Get event from modeling parameters 125 if (!fpModel) { 126 if (!fpModel) { 126 // No model - shouldn't happen 127 // No model - shouldn't happen 127 glFlush(); 128 glFlush(); 128 return; 129 return; 129 } 130 } 130 const G4ModelingParameters* modelingParame 131 const G4ModelingParameters* modelingParameters = 131 fpModel->GetModelingParameters(); 132 fpModel->GetModelingParameters(); 132 if (!modelingParameters) { 133 if (!modelingParameters) { 133 // No modeling parameters - shouldn't ha 134 // No modeling parameters - shouldn't happen 134 glFlush(); 135 glFlush(); 135 return; 136 return; 136 } 137 } 137 const G4Event* thisEvent = modelingParamet 138 const G4Event* thisEvent = modelingParameters->GetEvent(); 138 if (!thisEvent) { 139 if (!thisEvent) { 139 // No event, so not in event loop. 140 // No event, so not in event loop. 140 if (fFlushAction == endOfEvent) { 141 if (fFlushAction == endOfEvent) { 141 fFlushAction = endOfRun; 142 fFlushAction = endOfRun; 142 } else if (fFlushAction == NthEvent) { 143 } else if (fFlushAction == NthEvent) { 143 fFlushAction = NthPrimitive; 144 fFlushAction = NthPrimitive; 144 } 145 } 145 } 146 } 146 G4RunManager* runMan = G4RunManagerFactory 147 G4RunManager* runMan = G4RunManagerFactory::GetMasterRunManager(); 147 if (!runMan) { 148 if (!runMan) { 148 // No run manager - shouldn't happen 149 // No run manager - shouldn't happen 149 glFlush(); 150 glFlush(); 150 return; 151 return; 151 } 152 } 152 const G4Run* thisRun = runMan->GetCurrentR 153 const G4Run* thisRun = runMan->GetCurrentRun(); 153 if (!thisRun) { 154 if (!thisRun) { 154 // No run, so not in event loop. 155 // No run, so not in event loop. 155 if (fFlushAction == endOfRun) { 156 if (fFlushAction == endOfRun) { 156 fFlushAction = NthPrimitive; 157 fFlushAction = NthPrimitive; 157 } else if (fFlushAction == NthEvent) { 158 } else if (fFlushAction == NthEvent) { 158 fFlushAction = NthPrimitive; 159 fFlushAction = NthPrimitive; 159 } 160 } 160 } 161 } 161 162 162 switch (fFlushAction) { 163 switch (fFlushAction) { 163 case endOfEvent: 164 case endOfEvent: 164 // If "/vis/scene/endOfEventAction ref 165 // If "/vis/scene/endOfEventAction refresh", primitives are flushed at 165 // end of run anyway, so only scale if 166 // end of run anyway, so only scale if false. 166 if (!fpScene->GetRefreshAtEndOfEvent() 167 if (!fpScene->GetRefreshAtEndOfEvent()) { 167 // But if "/vis/scene/endOfEventActi 168 // But if "/vis/scene/endOfEventAction accumulate", ShowView is not 168 // called until end of run, so we ha 169 // called until end of run, so we have to watch for a new event. 169 // Get event from modeling parameter 170 // Get event from modeling parameters 170 G4int thisEventID = thisEvent->GetEv 171 G4int thisEventID = thisEvent->GetEventID(); 171 static G4int lastEventID = 0; 172 static G4int lastEventID = 0; 172 if (thisEventID != lastEventID) { 173 if (thisEventID != lastEventID) { 173 glFlush(); 174 glFlush(); 174 lastEventID = thisEventID; 175 lastEventID = thisEventID; 175 } 176 } 176 } 177 } 177 break; 178 break; 178 case endOfRun: 179 case endOfRun: 179 // If "/vis/scene/endOfRunAction refre 180 // If "/vis/scene/endOfRunAction refresh", primitives are flushed at 180 // end of run anyway, so only scale if 181 // end of run anyway, so only scale if false. 181 if (!fpScene->GetRefreshAtEndOfRun()) 182 if (!fpScene->GetRefreshAtEndOfRun()) { 182 // If "/vis/scene/endOfRunAction acc 183 // If "/vis/scene/endOfRunAction accumulate", ShowView is never called 183 // so we have to watch for a new run 184 // so we have to watch for a new run. 184 G4int thisRunID = thisRun->GetRunID( 185 G4int thisRunID = thisRun->GetRunID(); 185 static G4int lastRunID = 0; 186 static G4int lastRunID = 0; 186 if (thisRunID != lastRunID) { 187 if (thisRunID != lastRunID) { 187 glFlush(); 188 glFlush(); 188 lastRunID = thisRunID; 189 lastRunID = thisRunID; 189 } 190 } 190 } 191 } 191 break; 192 break; 192 case eachPrimitive: 193 case eachPrimitive: 193 // This is equivalent to numeric with 194 // This is equivalent to numeric with fEntitiesFlushInterval == 1. 194 fEntitiesFlushInterval = 1; << 195 fEntitiesFlushInterval = 1; // fallthrough 195 [[fallthrough]]; // Fall through to NthPrim << 196 // Fall through to NthPrimitive. 196 case NthPrimitive: 197 case NthPrimitive: 197 { // Encapsulate in scope {} brackets to 198 { // Encapsulate in scope {} brackets to satisfy Windows. 198 static G4int primitivesWaitingToBeFlus 199 static G4int primitivesWaitingToBeFlushed = 0; 199 primitivesWaitingToBeFlushed++; 200 primitivesWaitingToBeFlushed++; 200 if (primitivesWaitingToBeFlushed < fEn 201 if (primitivesWaitingToBeFlushed < fEntitiesFlushInterval) return; 201 glFlush(); 202 glFlush(); 202 primitivesWaitingToBeFlushed = 0; 203 primitivesWaitingToBeFlushed = 0; 203 break; 204 break; 204 } 205 } 205 case NthEvent: 206 case NthEvent: 206 // If "/vis/scene/endOfEventAction ref 207 // If "/vis/scene/endOfEventAction refresh", primitives are flushed at 207 // end of event anyway, so only scale 208 // end of event anyway, so only scale if false. 208 if (!fpScene->GetRefreshAtEndOfEvent() 209 if (!fpScene->GetRefreshAtEndOfEvent()) { 209 G4int thisEventID = thisEvent->GetEv 210 G4int thisEventID = thisEvent->GetEventID(); 210 static G4int lastEventID = 0; 211 static G4int lastEventID = 0; 211 if (thisEventID != lastEventID) { 212 if (thisEventID != lastEventID) { 212 static G4int eventsWaitingToBeFlus 213 static G4int eventsWaitingToBeFlushed = 0; 213 eventsWaitingToBeFlushed++; 214 eventsWaitingToBeFlushed++; 214 if (eventsWaitingToBeFlushed < fEn 215 if (eventsWaitingToBeFlushed < fEntitiesFlushInterval) return; 215 glFlush(); 216 glFlush(); 216 eventsWaitingToBeFlushed = 0; 217 eventsWaitingToBeFlushed = 0; 217 lastEventID = thisEventID; 218 lastEventID = thisEventID; 218 } 219 } 219 } 220 } 220 break; 221 break; 221 case never: 222 case never: 222 break; 223 break; 223 default: 224 default: 224 break; 225 break; 225 } 226 } 226 227 227 } 228 } 228 229 229 else 230 else 230 231 231 { 232 { 232 233 233 // For run duration model drawing (detecto 234 // For run duration model drawing (detector drawing): 234 // Immediate mode: a huge speed up is obta 235 // Immediate mode: a huge speed up is obtained if flushes are scaled. 235 // Stored mode: no discernable difference 236 // Stored mode: no discernable difference since drawing is done to the 236 // back buffer and then swapped. 237 // back buffer and then swapped. 237 // So eachPrimitive and NthPrimitive make 238 // So eachPrimitive and NthPrimitive make sense. But endOfEvent and 238 // endOfRun are treated as "no action", i. 239 // endOfRun are treated as "no action", i.e., a flush will only be issued, 239 // as happens anyway, when drawing is comp 240 // as happens anyway, when drawing is complete. 240 241 241 switch (fFlushAction) { 242 switch (fFlushAction) { 242 case endOfEvent: 243 case endOfEvent: 243 break; 244 break; 244 case endOfRun: 245 case endOfRun: 245 break; 246 break; 246 case eachPrimitive: 247 case eachPrimitive: 247 // This is equivalent to NthPrimitive 248 // This is equivalent to NthPrimitive with fEntitiesFlushInterval == 1. 248 fEntitiesFlushInterval = 1; << 249 fEntitiesFlushInterval = 1; // fallthrough 249 [[fallthrough]]; // Fall through to NthPrim << 250 // Fall through to NthPrimitive. 250 case NthPrimitive: 251 case NthPrimitive: 251 { // Encapsulate in scope {} brackets to 252 { // Encapsulate in scope {} brackets to satisfy Windows. 252 static G4int primitivesWaitingToBeFlus 253 static G4int primitivesWaitingToBeFlushed = 0; 253 primitivesWaitingToBeFlushed++; 254 primitivesWaitingToBeFlushed++; 254 if (primitivesWaitingToBeFlushed < fEn 255 if (primitivesWaitingToBeFlushed < fEntitiesFlushInterval) return; 255 glFlush(); 256 glFlush(); 256 primitivesWaitingToBeFlushed = 0; 257 primitivesWaitingToBeFlushed = 0; 257 break; 258 break; 258 } 259 } 259 case NthEvent: 260 case NthEvent: 260 break; 261 break; 261 case never: 262 case never: 262 break; 263 break; 263 default: 264 default: 264 break; 265 break; 265 } 266 } 266 267 267 } 268 } 268 } 269 } 269 270 270 void G4OpenGLSceneHandler::ProcessScene() 271 void G4OpenGLSceneHandler::ProcessScene() 271 { 272 { 272 fThreePassCapable = true; 273 fThreePassCapable = true; 273 274 274 G4VSceneHandler::ProcessScene(); 275 G4VSceneHandler::ProcessScene(); 275 276 276 // Repeat if required... 277 // Repeat if required... 277 if (fSecondPassForTransparencyRequested) { 278 if (fSecondPassForTransparencyRequested) { 278 fSecondPassForTransparency = true; 279 fSecondPassForTransparency = true; 279 G4VSceneHandler::ProcessScene(); 280 G4VSceneHandler::ProcessScene(); 280 fSecondPassForTransparency = false; 281 fSecondPassForTransparency = false; 281 fSecondPassForTransparencyRequested = fals 282 fSecondPassForTransparencyRequested = false; 282 } 283 } 283 284 284 // And again if required... 285 // And again if required... 285 if (fThirdPassForNonHiddenMarkersRequested) 286 if (fThirdPassForNonHiddenMarkersRequested) { 286 fThirdPassForNonHiddenMarkers = true; 287 fThirdPassForNonHiddenMarkers = true; 287 G4VSceneHandler::ProcessScene(); 288 G4VSceneHandler::ProcessScene(); 288 fThirdPassForNonHiddenMarkers = false; 289 fThirdPassForNonHiddenMarkers = false; 289 fThirdPassForNonHiddenMarkersRequested = f 290 fThirdPassForNonHiddenMarkersRequested = false; 290 } 291 } 291 292 292 fThreePassCapable = false; 293 fThreePassCapable = false; 293 } 294 } 294 295 295 void G4OpenGLSceneHandler::PreAddSolid 296 void G4OpenGLSceneHandler::PreAddSolid 296 (const G4Transform3D& objectTransformation, 297 (const G4Transform3D& objectTransformation, 297 const G4VisAttributes& visAttribs) 298 const G4VisAttributes& visAttribs) 298 { 299 { 299 G4VSceneHandler::PreAddSolid (objectTransfor 300 G4VSceneHandler::PreAddSolid (objectTransformation, visAttribs); 300 } 301 } 301 302 302 void G4OpenGLSceneHandler::BeginPrimitives 303 void G4OpenGLSceneHandler::BeginPrimitives 303 (const G4Transform3D& objectTransformation) 304 (const G4Transform3D& objectTransformation) 304 { 305 { 305 G4VSceneHandler::BeginPrimitives (objectTran 306 G4VSceneHandler::BeginPrimitives (objectTransformation); 306 } 307 } 307 308 308 void G4OpenGLSceneHandler::EndPrimitives () 309 void G4OpenGLSceneHandler::EndPrimitives () 309 { 310 { 310 G4VSceneHandler::EndPrimitives (); 311 G4VSceneHandler::EndPrimitives (); 311 } 312 } 312 313 313 void G4OpenGLSceneHandler::BeginPrimitives2D 314 void G4OpenGLSceneHandler::BeginPrimitives2D 314 (const G4Transform3D& objectTransformation) 315 (const G4Transform3D& objectTransformation) 315 { 316 { 316 G4VSceneHandler::BeginPrimitives2D (objectTr 317 G4VSceneHandler::BeginPrimitives2D (objectTransformation); 317 } 318 } 318 319 319 void G4OpenGLSceneHandler::EndPrimitives2D () 320 void G4OpenGLSceneHandler::EndPrimitives2D () 320 { 321 { 321 G4VSceneHandler::EndPrimitives2D (); 322 G4VSceneHandler::EndPrimitives2D (); 322 } 323 } 323 324 324 G4DisplacedSolid* G4OpenGLSceneHandler::Create 325 G4DisplacedSolid* G4OpenGLSceneHandler::CreateSectionSolid () 325 { 326 { 326 return G4VSceneHandler::CreateSectionSolid() 327 return G4VSceneHandler::CreateSectionSolid(); 327 // If clipping done in G4OpenGLViewer::SetVi 328 // If clipping done in G4OpenGLViewer::SetView 328 // return 0; 329 // return 0; 329 // Note: if you change this, you must also c 330 // Note: if you change this, you must also change 330 // G4OpenGLStoredViewer::CompareForKernelVis 331 // G4OpenGLStoredViewer::CompareForKernelVisit 331 } 332 } 332 333 333 G4DisplacedSolid* G4OpenGLSceneHandler::Create 334 G4DisplacedSolid* G4OpenGLSceneHandler::CreateCutawaySolid () 334 { 335 { 335 // return G4VSceneHandler::CreateCutawaySoli 336 // return G4VSceneHandler::CreateCutawaySolid(); 336 // If cutaway done in G4OpenGLViewer::SetVie 337 // If cutaway done in G4OpenGLViewer::SetView. 337 return 0; 338 return 0; 338 // Note: if you change this, you must also c 339 // Note: if you change this, you must also change 339 // G4OpenGLStoredViewer::CompareForKernelVis 340 // G4OpenGLStoredViewer::CompareForKernelVisit 340 } 341 } 341 342 342 void G4OpenGLSceneHandler::AddPrimitive (const 343 void G4OpenGLSceneHandler::AddPrimitive (const G4Polyline& line) 343 { 344 { 344 std::size_t nPoints = line.size (); << 345 G4int nPoints = line.size (); 345 if (nPoints <= 0) return; 346 if (nPoints <= 0) return; 346 347 347 // Note: colour and depth test treated in su 348 // Note: colour and depth test treated in sub-class. 348 349 >> 350 #ifndef G4OPENGL_VERSION_2 349 glDisable (GL_LIGHTING); 351 glDisable (GL_LIGHTING); >> 352 #endif 350 353 351 G4double lineWidth = GetLineWidth(fpVisAttri 354 G4double lineWidth = GetLineWidth(fpVisAttribs); 352 // Need access to method in G4OpenGLViewer. 355 // Need access to method in G4OpenGLViewer. static_cast doesn't 353 // work with a virtual base class, so use dy 356 // work with a virtual base class, so use dynamic_cast. No need to 354 // test the outcome since viewer is guarante 357 // test the outcome since viewer is guaranteed to be a 355 // G4OpenGLViewer, but test it anyway to kee 358 // G4OpenGLViewer, but test it anyway to keep Coverity happy. 356 G4OpenGLViewer* pGLViewer = dynamic_cast<G4O 359 G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer); 357 if (pGLViewer) pGLViewer->ChangeLineWidth(li 360 if (pGLViewer) pGLViewer->ChangeLineWidth(lineWidth); 358 361 359 fEdgeFlag = true; 362 fEdgeFlag = true; >> 363 #ifndef G4OPENGL_VERSION_2 360 glBegin (GL_LINE_STRIP); 364 glBegin (GL_LINE_STRIP); 361 // No ned glEdgeFlag for lines : 365 // No ned glEdgeFlag for lines : 362 // Boundary and nonboundary edge flags on ve 366 // Boundary and nonboundary edge flags on vertices are significant only if GL_POLYGON_MODE is set to GL_POINT or GL_LINE. See glPolygonMode. 363 367 364 // glEdgeFlag (GL_TRUE); 368 // glEdgeFlag (GL_TRUE); 365 for (std::size_t iPoint = 0; iPoint < nPoint << 369 for (G4int iPoint = 0; iPoint < nPoints; iPoint++) { 366 G4double x, y, z; 370 G4double x, y, z; 367 x = line[iPoint].x(); 371 x = line[iPoint].x(); 368 y = line[iPoint].y(); 372 y = line[iPoint].y(); 369 z = line[iPoint].z(); 373 z = line[iPoint].z(); 370 glVertex3d (x, y, z); 374 glVertex3d (x, y, z); 371 } 375 } 372 glEnd (); 376 glEnd (); >> 377 #else >> 378 glBeginVBO(GL_LINE_STRIP); >> 379 >> 380 for (G4int iPoint = 0; iPoint < nPoints; iPoint++) { >> 381 fOglVertex.push_back(line[iPoint].x()); >> 382 fOglVertex.push_back(line[iPoint].y()); >> 383 fOglVertex.push_back(line[iPoint].z()); >> 384 // normal >> 385 fOglVertex.push_back(0); >> 386 fOglVertex.push_back(0); >> 387 fOglVertex.push_back(1); >> 388 } >> 389 >> 390 glEndVBO(); >> 391 #endif 373 } 392 } 374 393 375 void G4OpenGLSceneHandler::AddPrimitive (const 394 void G4OpenGLSceneHandler::AddPrimitive (const G4Polymarker& polymarker) 376 { 395 { 377 if (polymarker.size() == 0) { 396 if (polymarker.size() == 0) { 378 return; 397 return; 379 } 398 } 380 399 381 // Note: colour and depth test treated in su 400 // Note: colour and depth test treated in sub-class. 382 401 >> 402 #ifndef G4OPENGL_VERSION_2 383 glDisable (GL_LIGHTING); 403 glDisable (GL_LIGHTING); >> 404 #endif 384 405 385 MarkerSizeType sizeType; 406 MarkerSizeType sizeType; 386 G4double size = GetMarkerSize(polymarker, si 407 G4double size = GetMarkerSize(polymarker, sizeType); 387 408 388 // Need access to method in G4OpenGLViewer. 409 // Need access to method in G4OpenGLViewer. static_cast doesn't 389 // work with a virtual base class, so use dy 410 // work with a virtual base class, so use dynamic_cast. No need to 390 // test the outcome since viewer is guarante 411 // test the outcome since viewer is guaranteed to be a 391 // G4OpenGLViewer, but test it anyway to kee 412 // G4OpenGLViewer, but test it anyway to keep Coverity happy. 392 G4OpenGLViewer* pGLViewer = dynamic_cast<G4O 413 G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer); 393 if (!pGLViewer) return; 414 if (!pGLViewer) return; 394 415 395 if (sizeType == world) { // Size specified 416 if (sizeType == world) { // Size specified in world coordinates. 396 G4double lineWidth = GetLineWidth(fpVisAtt 417 G4double lineWidth = GetLineWidth(fpVisAttribs); 397 pGLViewer->ChangeLineWidth(lineWidth); 418 pGLViewer->ChangeLineWidth(lineWidth); 398 419 399 G4VMarker::FillStyle style = polymarker.Ge 420 G4VMarker::FillStyle style = polymarker.GetFillStyle(); 400 421 401 // G4bool filled = false; Not actually us 422 // G4bool filled = false; Not actually used - comment out to prevent compiler warnings (JA). 402 static G4bool hashedWarned = false; 423 static G4bool hashedWarned = false; 403 424 404 switch (style) { 425 switch (style) { 405 case G4VMarker::noFill: 426 case G4VMarker::noFill: 406 glPolygonMode (GL_FRONT_AND_BACK, GL_L 427 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 407 glEdgeFlag (GL_TRUE); 428 glEdgeFlag (GL_TRUE); 408 //filled = false; 429 //filled = false; 409 break; 430 break; 410 case G4VMarker::hashed: 431 case G4VMarker::hashed: 411 if (!hashedWarned) { << 432 if (!hashedWarned) { // fallthrough 412 G4cout << "Hashed fill style in G4Op 433 G4cout << "Hashed fill style in G4OpenGLSceneHandler." 413 << "\n Not implemented. Using G4VM 434 << "\n Not implemented. Using G4VMarker::filled." 414 << G4endl; 435 << G4endl; 415 hashedWarned = true; 436 hashedWarned = true; 416 } << 437 } // fallthrough 417 // Maybe use 438 // Maybe use 418 //glPolygonStipple (fStippleMaskHashed 439 //glPolygonStipple (fStippleMaskHashed); 419 [[fallthrough]]; // Drop through to filled << 440 // Drop through to filled... 420 case G4VMarker::filled: 441 case G4VMarker::filled: 421 glPolygonMode (GL_FRONT_AND_BACK, GL_F 442 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 422 //filled = true; 443 //filled = true; 423 break; 444 break; 424 } 445 } 425 } 446 } 426 447 427 // Draw... 448 // Draw... 428 if (sizeType == world) { // Size specified 449 if (sizeType == world) { // Size specified in world coordinates. 429 450 430 G4int nSides; 451 G4int nSides; 431 G4double startPhi; 452 G4double startPhi; 432 switch (polymarker.GetMarkerType()) { 453 switch (polymarker.GetMarkerType()) { 433 default: 454 default: 434 case G4Polymarker::dots: 455 case G4Polymarker::dots: 435 size = 1.; << 456 size = 1.; // fallthrough 436 [[fallthrough]]; // Fall through to circles << 457 // Drop through to circles 437 case G4Polymarker::circles: 458 case G4Polymarker::circles: 438 nSides = GetNoOfSides(fpVisAttribs); 459 nSides = GetNoOfSides(fpVisAttribs); 439 startPhi = 0.; 460 startPhi = 0.; 440 break; 461 break; 441 case G4Polymarker::squares: 462 case G4Polymarker::squares: 442 nSides = 4; 463 nSides = 4; 443 startPhi = -pi / 4.; 464 startPhi = -pi / 4.; 444 break; 465 break; 445 } 466 } 446 467 447 const G4Vector3D& viewpointDirection = 468 const G4Vector3D& viewpointDirection = 448 fpViewer -> GetViewParameters().GetViewp 469 fpViewer -> GetViewParameters().GetViewpointDirection(); 449 const G4Vector3D& up = fpViewer->GetViewPa 470 const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector(); 450 const G4double dPhi = twopi / nSides; 471 const G4double dPhi = twopi / nSides; 451 const G4double radius = size / 2.; 472 const G4double radius = size / 2.; 452 G4Vector3D start = radius * (up.cross(view 473 G4Vector3D start = radius * (up.cross(viewpointDirection)).unit(); 453 G4double phi; 474 G4double phi; 454 G4int i; 475 G4int i; 455 for (size_t iPoint = 0; iPoint < polymarke 476 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) { 456 fEdgeFlag = true; 477 fEdgeFlag = true; >> 478 #ifndef G4OPENGL_VERSION_2 457 glBegin (GL_POLYGON); 479 glBegin (GL_POLYGON); 458 for (i = 0, phi = startPhi; i < nSides; 480 for (i = 0, phi = startPhi; i < nSides; i++, phi += dPhi) { 459 G4Vector3D r = start; r.rotate(phi, viewpoin 481 G4Vector3D r = start; r.rotate(phi, viewpointDirection); 460 G4Vector3D p = polymarker[iPoint] + r; 482 G4Vector3D p = polymarker[iPoint] + r; 461 glVertex3d (p.x(), p.y(), p.z()); 483 glVertex3d (p.x(), p.y(), p.z()); 462 } 484 } 463 glEnd (); 485 glEnd (); >> 486 #else >> 487 glBeginVBO (GL_TRIANGLE_STRIP); >> 488 for (i = 0, phi = startPhi; i < nSides; i++, phi += dPhi) { >> 489 G4Vector3D r = start; r.rotate(phi, viewpointDirection); >> 490 G4Vector3D p = polymarker[iPoint] + r; >> 491 >> 492 fOglVertex.push_back(p.x()); >> 493 fOglVertex.push_back(p.y()); >> 494 fOglVertex.push_back(p.z()); >> 495 // normal >> 496 fOglVertex.push_back(0); >> 497 fOglVertex.push_back(0); >> 498 fOglVertex.push_back(1); >> 499 } >> 500 glEndVBO (); >> 501 #endif 464 } 502 } 465 503 466 } else { // Size specified in screen (window 504 } else { // Size specified in screen (window) coordinates. 467 505 468 pGLViewer->ChangePointSize(size); 506 pGLViewer->ChangePointSize(size); 469 507 470 //Antialiasing only for circles 508 //Antialiasing only for circles >> 509 #ifndef G4OPENGL_VERSION_2 471 switch (polymarker.GetMarkerType()) { 510 switch (polymarker.GetMarkerType()) { 472 default: 511 default: 473 case G4Polymarker::dots: 512 case G4Polymarker::dots: 474 case G4Polymarker::circles: 513 case G4Polymarker::circles: 475 glEnable (GL_POINT_SMOOTH); break; 514 glEnable (GL_POINT_SMOOTH); break; 476 case G4Polymarker::squares: 515 case G4Polymarker::squares: 477 glDisable (GL_POINT_SMOOTH); break; 516 glDisable (GL_POINT_SMOOTH); break; 478 } 517 } >> 518 #endif >> 519 #ifndef G4OPENGL_VERSION_2 479 glBegin (GL_POINTS); 520 glBegin (GL_POINTS); 480 for (size_t iPoint = 0; iPoint < polymarke 521 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) { 481 G4Point3D centre = polymarker[iPoint]; 522 G4Point3D centre = polymarker[iPoint]; 482 glVertex3d(centre.x(),centre.y(),centre. 523 glVertex3d(centre.x(),centre.y(),centre.z()); 483 } 524 } 484 glEnd(); 525 glEnd(); >> 526 #else >> 527 glBeginVBO(GL_POINTS); >> 528 >> 529 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) { >> 530 fOglVertex.push_back(polymarker[iPoint].x()); >> 531 fOglVertex.push_back(polymarker[iPoint].y()); >> 532 fOglVertex.push_back(polymarker[iPoint].z()); >> 533 fOglVertex.push_back(0); >> 534 fOglVertex.push_back(0); >> 535 fOglVertex.push_back(1); >> 536 } >> 537 glEndVBO(); >> 538 #endif 485 } 539 } 486 } 540 } 487 541 488 void G4OpenGLSceneHandler::AddPrimitive (const 542 void G4OpenGLSceneHandler::AddPrimitive (const G4Text& text) { 489 // Pass to specific viewer via virtual funct 543 // Pass to specific viewer via virtual function DrawText. >> 544 // FIXME : Not ready for OPENGL2 for the moment >> 545 #ifdef G4OPENGL_VERSION_2 >> 546 return; >> 547 #endif 490 G4OpenGLViewer* pGLViewer = dynamic_cast<G4O 548 G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer); 491 if (pGLViewer) pGLViewer->DrawText(text); 549 if (pGLViewer) pGLViewer->DrawText(text); 492 } 550 } 493 551 494 void G4OpenGLSceneHandler::AddPrimitive (const 552 void G4OpenGLSceneHandler::AddPrimitive (const G4Circle& circle) { 495 G4Polymarker oneCircle(circle); 553 G4Polymarker oneCircle(circle); 496 oneCircle.push_back(circle.GetPosition()); 554 oneCircle.push_back(circle.GetPosition()); 497 oneCircle.SetMarkerType(G4Polymarker::circle 555 oneCircle.SetMarkerType(G4Polymarker::circles); 498 // Call this AddPrimitive to avoid re-doing 556 // Call this AddPrimitive to avoid re-doing sub-class code. 499 G4OpenGLSceneHandler::AddPrimitive(oneCircle 557 G4OpenGLSceneHandler::AddPrimitive(oneCircle); 500 } 558 } 501 559 502 void G4OpenGLSceneHandler::AddPrimitive (const 560 void G4OpenGLSceneHandler::AddPrimitive (const G4Square& square) { 503 G4Polymarker oneSquare(square); 561 G4Polymarker oneSquare(square); 504 oneSquare.push_back(square.GetPosition()); 562 oneSquare.push_back(square.GetPosition()); 505 oneSquare.SetMarkerType(G4Polymarker::square 563 oneSquare.SetMarkerType(G4Polymarker::squares); 506 // Call this AddPrimitive to avoid re-doing 564 // Call this AddPrimitive to avoid re-doing sub-class code. 507 G4OpenGLSceneHandler::AddPrimitive(oneSquare 565 G4OpenGLSceneHandler::AddPrimitive(oneSquare); 508 } 566 } 509 567 >> 568 void G4OpenGLSceneHandler::AddPrimitive (const G4Scale& scale) >> 569 { >> 570 G4VSceneHandler::AddPrimitive(scale); >> 571 } >> 572 510 //Method for handling G4Polyhedron objects for 573 //Method for handling G4Polyhedron objects for drawing solids. 511 void G4OpenGLSceneHandler::AddPrimitive (const 574 void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) { 512 575 513 // Assume all facets are planar convex quadr 576 // Assume all facets are planar convex quadrilaterals. 514 // Draw each facet individually 577 // Draw each facet individually 515 578 516 if (polyhedron.GetNoFacets() == 0) return; 579 if (polyhedron.GetNoFacets() == 0) return; 517 580 518 // Need access to data in G4OpenGLViewer. s 581 // Need access to data in G4OpenGLViewer. static_cast doesn't work 519 // with a virtual base class, so use dynamic 582 // with a virtual base class, so use dynamic_cast. 520 G4OpenGLViewer* pGLViewer = dynamic_cast<G4O 583 G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer); 521 if (!pGLViewer) return; 584 if (!pGLViewer) return; 522 585 523 // Get view parameters that the user can for 586 // Get view parameters that the user can force through the vis 524 // attributes, thereby over-riding the curre 587 // attributes, thereby over-riding the current view parameter. 525 G4ViewParameters::DrawingStyle drawing_style 588 G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (fpVisAttribs); 526 589 527 // Note that in stored mode, because this ca 590 // Note that in stored mode, because this call gets embedded in a display 528 // list, it is the colour _at the time of_ 591 // list, it is the colour _at the time of_ creation of the display list, so 529 // even if the colour is changed, for examp 592 // even if the colour is changed, for example, by interaction with a Qt 530 // window, current_colour does not change. 593 // window, current_colour does not change. 531 GLfloat* painting_colour; 594 GLfloat* painting_colour; 532 GLfloat clear_colour[4]; 595 GLfloat clear_colour[4]; 533 GLfloat current_colour[4]; 596 GLfloat current_colour[4]; 534 glGetFloatv (GL_CURRENT_COLOR, current_colou 597 glGetFloatv (GL_CURRENT_COLOR, current_colour); 535 598 536 G4bool isTransparent = false; 599 G4bool isTransparent = false; 537 if (current_colour[3] < 1.) { // This objec 600 if (current_colour[3] < 1.) { // This object is transparent 538 isTransparent = true; 601 isTransparent = true; 539 } 602 } 540 603 541 if (drawing_style == G4ViewParameters::hlr) 604 if (drawing_style == G4ViewParameters::hlr) { 542 // This is the colour used to paint surfac 605 // This is the colour used to paint surfaces in hlr mode. 543 glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_c 606 glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour); 544 painting_colour = clear_colour; 607 painting_colour = clear_colour; 545 } else { // drawing_style == G4ViewParamete 608 } else { // drawing_style == G4ViewParameters::hlhsr 546 painting_colour = current_colour; 609 painting_colour = current_colour; 547 } 610 } 548 611 549 G4double lineWidth = GetLineWidth(fpVisAttri 612 G4double lineWidth = GetLineWidth(fpVisAttribs); 550 pGLViewer->ChangeLineWidth(lineWidth); 613 pGLViewer->ChangeLineWidth(lineWidth); 551 614 552 G4bool isAuxEdgeVisible = GetAuxEdgeVisible 615 G4bool isAuxEdgeVisible = GetAuxEdgeVisible (fpVisAttribs); 553 616 554 G4bool clipping = pGLViewer->fVP.IsSection() 617 G4bool clipping = pGLViewer->fVP.IsSection() || pGLViewer->fVP.IsCutaway(); 555 618 556 // Lighting disabled unless otherwise reques 619 // Lighting disabled unless otherwise requested >> 620 #ifndef G4OPENGL_VERSION_2 557 glDisable (GL_LIGHTING); 621 glDisable (GL_LIGHTING); >> 622 #endif 558 623 559 switch (drawing_style) { 624 switch (drawing_style) { 560 case (G4ViewParameters::hlhsr): 625 case (G4ViewParameters::hlhsr): 561 // Set up as for hidden line removal but p 626 // Set up as for hidden line removal but paint polygon faces later... 562 case (G4ViewParameters::hlr): 627 case (G4ViewParameters::hlr): 563 glEnable (GL_STENCIL_TEST); 628 glEnable (GL_STENCIL_TEST); 564 // The stencil buffer is cleared in G4Open 629 // The stencil buffer is cleared in G4OpenGLViewer::ClearView. 565 // The procedure below leaves it clear. 630 // The procedure below leaves it clear. 566 glStencilFunc (GL_ALWAYS, 0, 1); 631 glStencilFunc (GL_ALWAYS, 0, 1); 567 glStencilOp (GL_INVERT, GL_INVERT, GL_INVE 632 glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT); 568 glEnable (GL_DEPTH_TEST); 633 glEnable (GL_DEPTH_TEST); 569 glDepthFunc (GL_LEQUAL); 634 glDepthFunc (GL_LEQUAL); 570 if (isTransparent) { 635 if (isTransparent) { 571 // Transparent... 636 // Transparent... 572 glColorMaterial(GL_FRONT_AND_BACK, GL_AM 637 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); 573 glEnable(GL_COLOR_MATERIAL); 638 glEnable(GL_COLOR_MATERIAL); 574 //glDisable (GL_CULL_FACE); << 639 glDisable (GL_CULL_FACE); 575 glPolygonMode (GL_FRONT_AND_BACK, GL_LIN 640 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 576 } else { 641 } else { 577 // Opaque... 642 // Opaque... 578 if (clipping) { 643 if (clipping) { 579 glColorMaterial(GL_FRONT_AND_BACK, GL_ 644 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); 580 glEnable(GL_COLOR_MATERIAL); 645 glEnable(GL_COLOR_MATERIAL); 581 //glDisable (GL_CULL_FACE); << 646 glDisable (GL_CULL_FACE); 582 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 647 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 583 } else { 648 } else { 584 glColorMaterial(GL_FRONT, GL_AMBIENT_A 649 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); 585 glEnable(GL_COLOR_MATERIAL); 650 glEnable(GL_COLOR_MATERIAL); 586 //glEnable (GL_CULL_FACE); << 651 glEnable (GL_CULL_FACE); 587 //glCullFace (GL_BACK); << 652 glCullFace (GL_BACK); 588 glPolygonMode (GL_FRONT, GL_LINE); 653 glPolygonMode (GL_FRONT, GL_LINE); 589 } 654 } 590 } 655 } 591 break; 656 break; 592 case (G4ViewParameters::hsr): 657 case (G4ViewParameters::hsr): 593 glEnable (GL_DEPTH_TEST); 658 glEnable (GL_DEPTH_TEST); 594 glDepthFunc (GL_LEQUAL); 659 glDepthFunc (GL_LEQUAL); 595 if (isTransparent) { 660 if (isTransparent) { 596 // Transparent... 661 // Transparent... 597 glDepthMask (GL_FALSE); // Make depth b 662 glDepthMask (GL_FALSE); // Make depth buffer read-only. 598 glColorMaterial(GL_FRONT_AND_BACK, GL_AM 663 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); >> 664 #ifndef G4OPENGL_VERSION_2 599 glEnable(GL_COLOR_MATERIAL); 665 glEnable(GL_COLOR_MATERIAL); 600 //glDisable (GL_CULL_FACE); << 666 #endif >> 667 glDisable (GL_CULL_FACE); 601 glPolygonMode (GL_FRONT_AND_BACK, GL_FIL 668 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 602 } else { 669 } else { 603 // Opaque... 670 // Opaque... 604 glDepthMask (GL_TRUE); // Make depth bu 671 glDepthMask (GL_TRUE); // Make depth buffer writable (default). 605 if (clipping) { 672 if (clipping) { 606 glColorMaterial(GL_FRONT_AND_BACK, GL_ 673 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); 607 glEnable(GL_COLOR_MATERIAL); 674 glEnable(GL_COLOR_MATERIAL); 608 //glDisable (GL_CULL_FACE); << 675 glDisable (GL_CULL_FACE); 609 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 676 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 610 } else { 677 } else { 611 glColorMaterial(GL_FRONT, GL_AMBIENT_A 678 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); >> 679 #ifndef G4OPENGL_VERSION_2 612 glEnable(GL_COLOR_MATERIAL); 680 glEnable(GL_COLOR_MATERIAL); 613 //glEnable (GL_CULL_FACE); << 681 #endif 614 //glCullFace (GL_BACK); << 682 glEnable (GL_CULL_FACE); >> 683 glCullFace (GL_BACK); 615 glPolygonMode (GL_FRONT, GL_FILL); 684 glPolygonMode (GL_FRONT, GL_FILL); 616 } 685 } 617 } 686 } >> 687 #ifndef G4OPENGL_VERSION_2 618 if (!fProcessing2D) glEnable (GL_LIGHTING) 688 if (!fProcessing2D) glEnable (GL_LIGHTING); >> 689 #endif 619 break; 690 break; 620 case (G4ViewParameters::wireframe): 691 case (G4ViewParameters::wireframe): 621 default: 692 default: 622 glEnable (GL_DEPTH_TEST); 693 glEnable (GL_DEPTH_TEST); 623 glDepthFunc (GL_LEQUAL); //??? was GL_A 694 glDepthFunc (GL_LEQUAL); //??? was GL_ALWAYS 624 //glDisable (GL_CULL_FACE); << 695 glDisable (GL_CULL_FACE); 625 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE) 696 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 626 break; 697 break; 627 } 698 } 628 699 629 //Loop through all the facets... 700 //Loop through all the facets... 630 fEdgeFlag = true; 701 fEdgeFlag = true; >> 702 #ifndef G4OPENGL_VERSION_2 631 glBegin (GL_QUADS); 703 glBegin (GL_QUADS); 632 glEdgeFlag (GL_TRUE); 704 glEdgeFlag (GL_TRUE); >> 705 #else >> 706 fEmulate_GL_QUADS = true; >> 707 glBeginVBO(GL_TRIANGLE_STRIP); >> 708 #endif 633 G4bool notLastFace; 709 G4bool notLastFace; 634 do { 710 do { 635 711 636 //First, find vertices, edgeflags and norm 712 //First, find vertices, edgeflags and normals and note "not last facet"... 637 G4Point3D vertex[4]; 713 G4Point3D vertex[4]; 638 G4int edgeFlag[4]; 714 G4int edgeFlag[4]; 639 G4Normal3D normals[4]; 715 G4Normal3D normals[4]; 640 G4int nEdges; 716 G4int nEdges; 641 notLastFace = polyhedron.GetNextFacet(nEdg 717 notLastFace = polyhedron.GetNextFacet(nEdges, vertex, edgeFlag, normals); 642 718 643 //Loop through the four edges of each G4Fa 719 //Loop through the four edges of each G4Facet... 644 for(G4int edgeCount = 0; edgeCount < nEdge 720 for(G4int edgeCount = 0; edgeCount < nEdges; ++edgeCount) { 645 // Check to see if edge is visible or no 721 // Check to see if edge is visible or not... 646 if (isAuxEdgeVisible) { 722 if (isAuxEdgeVisible) { 647 edgeFlag[edgeCount] = 1; 723 edgeFlag[edgeCount] = 1; 648 } 724 } >> 725 #ifndef G4OPENGL_VERSION_2 649 if (edgeFlag[edgeCount] > 0) { 726 if (edgeFlag[edgeCount] > 0) { 650 if (fEdgeFlag != true) { 727 if (fEdgeFlag != true) { 651 glEdgeFlag (GL_TRUE); 728 glEdgeFlag (GL_TRUE); 652 fEdgeFlag = true; 729 fEdgeFlag = true; 653 } 730 } 654 } else { 731 } else { 655 if (fEdgeFlag != false) { 732 if (fEdgeFlag != false) { 656 glEdgeFlag (GL_FALSE); 733 glEdgeFlag (GL_FALSE); 657 fEdgeFlag = false; 734 fEdgeFlag = false; 658 } 735 } 659 } 736 } 660 glNormal3d (normals[edgeCount].x(), 737 glNormal3d (normals[edgeCount].x(), 661 normals[edgeCount].y(), 738 normals[edgeCount].y(), 662 normals[edgeCount].z()); 739 normals[edgeCount].z()); 663 glVertex3d (vertex[edgeCount].x(), 740 glVertex3d (vertex[edgeCount].x(), 664 vertex[edgeCount].y(), 741 vertex[edgeCount].y(), 665 vertex[edgeCount].z()); 742 vertex[edgeCount].z()); >> 743 #else >> 744 >> 745 fOglVertex.push_back(vertex[edgeCount].x()); >> 746 fOglVertex.push_back(vertex[edgeCount].y()); >> 747 fOglVertex.push_back(vertex[edgeCount].z()); >> 748 >> 749 fOglVertex.push_back(normals[edgeCount].x()); >> 750 fOglVertex.push_back(normals[edgeCount].y()); >> 751 fOglVertex.push_back(normals[edgeCount].z()); >> 752 >> 753 #endif >> 754 666 } 755 } 667 756 668 // HepPolyhedron produces triangles too; i 757 // HepPolyhedron produces triangles too; in that case add an extra 669 // vertex identical to first... 758 // vertex identical to first... 670 if (nEdges == 3) { 759 if (nEdges == 3) { 671 G4int edgeCount = 3; 760 G4int edgeCount = 3; 672 normals[edgeCount] = normals[0]; 761 normals[edgeCount] = normals[0]; 673 vertex[edgeCount] = vertex[0]; 762 vertex[edgeCount] = vertex[0]; >> 763 #ifndef G4OPENGL_VERSION_2 674 edgeFlag[edgeCount] = -1; 764 edgeFlag[edgeCount] = -1; 675 if (fEdgeFlag != false) { 765 if (fEdgeFlag != false) { 676 glEdgeFlag (GL_FALSE); 766 glEdgeFlag (GL_FALSE); 677 fEdgeFlag = false; 767 fEdgeFlag = false; 678 } 768 } 679 769 680 glNormal3d (normals[edgeCount].x(), 770 glNormal3d (normals[edgeCount].x(), 681 normals[edgeCount].y(), 771 normals[edgeCount].y(), 682 normals[edgeCount].z()); 772 normals[edgeCount].z()); 683 glVertex3d (vertex[edgeCount].x(), 773 glVertex3d (vertex[edgeCount].x(), 684 vertex[edgeCount].y(), 774 vertex[edgeCount].y(), 685 vertex[edgeCount].z()); 775 vertex[edgeCount].z()); >> 776 #else >> 777 fOglVertex.push_back(vertex[edgeCount].x()); >> 778 fOglVertex.push_back(vertex[edgeCount].y()); >> 779 fOglVertex.push_back(vertex[edgeCount].z()); >> 780 >> 781 fOglVertex.push_back(normals[edgeCount].x()); >> 782 fOglVertex.push_back(normals[edgeCount].y()); >> 783 fOglVertex.push_back(normals[edgeCount].z()); >> 784 >> 785 #endif 686 } 786 } 687 // Trap situation where number of edges is 787 // Trap situation where number of edges is > 4... 688 if (nEdges > 4) { 788 if (nEdges > 4) { 689 G4cerr << 789 G4cerr << 690 "G4OpenGLSceneHandler::AddPrimitive(G4Polyhe 790 "G4OpenGLSceneHandler::AddPrimitive(G4Polyhedron): WARNING" 691 "\n G4Polyhedron facet with " << nEdges << 791 "\n G4Polyhedron facet with " << nEdges << " edges" << G4endl; 692 } 792 } 693 793 694 794 695 // Do it all over again (twice) for hlr... 795 // Do it all over again (twice) for hlr... 696 if (drawing_style == G4ViewParameters::hl 796 if (drawing_style == G4ViewParameters::hlr || 697 drawing_style == G4ViewParameters::hlhsr) { 797 drawing_style == G4ViewParameters::hlhsr) { 698 798 >> 799 #ifndef G4OPENGL_VERSION_2 699 glDisable(GL_COLOR_MATERIAL); // Revert 800 glDisable(GL_COLOR_MATERIAL); // Revert to glMaterial for hlr/sr. >> 801 #endif >> 802 >> 803 #ifndef G4OPENGL_VERSION_2 700 glEnd (); // Placed here to balance glB 804 glEnd (); // Placed here to balance glBegin above, allowing GL 701 << 805 #else >> 806 glEndVBO(); >> 807 #endif 702 // state changes below, then glBegin aga 808 // state changes below, then glBegin again. Avoids 703 // having glBegin/End pairs *inside* loop 809 // having glBegin/End pairs *inside* loop in the more 704 // usual case of no hidden line removal. 810 // usual case of no hidden line removal. 705 811 706 // Lighting disabled unless otherwise re 812 // Lighting disabled unless otherwise requested 707 glDisable (GL_LIGHTING); 813 glDisable (GL_LIGHTING); 708 814 709 // Draw through stencil... 815 // Draw through stencil... 710 glStencilFunc (GL_EQUAL, 0, 1); 816 glStencilFunc (GL_EQUAL, 0, 1); 711 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); 817 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); 712 if (drawing_style == G4ViewParameters::h 818 if (drawing_style == G4ViewParameters::hlhsr) { 713 if (!fProcessing2D) glEnable (GL_LIGHTING); 819 if (!fProcessing2D) glEnable (GL_LIGHTING); 714 } 820 } 715 glEnable (GL_DEPTH_TEST); 821 glEnable (GL_DEPTH_TEST); 716 glDepthFunc (GL_LEQUAL); 822 glDepthFunc (GL_LEQUAL); 717 if (isTransparent) { 823 if (isTransparent) { 718 // Transparent... 824 // Transparent... 719 glDepthMask (GL_FALSE); // Make depth buffe 825 glDepthMask (GL_FALSE); // Make depth buffer read-only. 720 //glDisable (GL_CULL_FACE); << 826 glDisable (GL_CULL_FACE); 721 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 827 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 722 } else { 828 } else { 723 // Opaque... 829 // Opaque... 724 glDepthMask (GL_TRUE); // Make depth buffer 830 glDepthMask (GL_TRUE); // Make depth buffer writable (default). 725 if (clipping) { 831 if (clipping) { 726 //glDisable (GL_CULL_FACE); << 832 glDisable (GL_CULL_FACE); 727 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL) 833 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 728 } else { 834 } else { 729 //glEnable (GL_CULL_FACE); << 835 glEnable (GL_CULL_FACE); 730 //glCullFace (GL_BACK); << 836 glCullFace (GL_BACK); 731 glPolygonMode (GL_FRONT, GL_FILL); 837 glPolygonMode (GL_FRONT, GL_FILL); 732 } 838 } 733 } 839 } 734 if (drawing_style == G4ViewParameters:: 840 if (drawing_style == G4ViewParameters::hlr) { 735 if (isTransparent) { 841 if (isTransparent) { 736 // Transparent - don't paint... 842 // Transparent - don't paint... 737 goto end_of_drawing_through_stencil; 843 goto end_of_drawing_through_stencil; 738 } 844 } 739 } 845 } 740 if (isTransparent) { 846 if (isTransparent) { 741 // Transparent... 847 // Transparent... 742 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_ 848 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, painting_colour); 743 } else { 849 } else { 744 // Opaque... 850 // Opaque... 745 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFU 851 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, painting_colour); 746 } 852 } 747 glColor4fv (painting_colour); 853 glColor4fv (painting_colour); >> 854 #ifndef G4OPENGL_VERSION_2 748 glBegin (GL_QUADS); 855 glBegin (GL_QUADS); 749 glEdgeFlag (GL_TRUE); 856 glEdgeFlag (GL_TRUE); 750 fEdgeFlag = true; 857 fEdgeFlag = true; >> 858 #else >> 859 fEmulate_GL_QUADS = true; >> 860 glBeginVBO(GL_TRIANGLE_STRIP); >> 861 #endif 751 862 752 for (int edgeCount = 0; edgeCount < 4; + 863 for (int edgeCount = 0; edgeCount < 4; ++edgeCount) { >> 864 #ifndef G4OPENGL_VERSION_2 753 if (edgeFlag[edgeCount] > 0) { 865 if (edgeFlag[edgeCount] > 0) { 754 if (fEdgeFlag != true) { 866 if (fEdgeFlag != true) { 755 glEdgeFlag (GL_TRUE); 867 glEdgeFlag (GL_TRUE); 756 fEdgeFlag = true; 868 fEdgeFlag = true; 757 } 869 } 758 } else { 870 } else { 759 if (fEdgeFlag != false) { 871 if (fEdgeFlag != false) { 760 glEdgeFlag (GL_FALSE); 872 glEdgeFlag (GL_FALSE); 761 fEdgeFlag = false; 873 fEdgeFlag = false; 762 } 874 } 763 } 875 } 764 glNormal3d (normals[edgeCount].x(), 876 glNormal3d (normals[edgeCount].x(), 765 normals[edgeCount].y(), 877 normals[edgeCount].y(), 766 normals[edgeCount].z()); 878 normals[edgeCount].z()); 767 glVertex3d (vertex[edgeCount].x(), 879 glVertex3d (vertex[edgeCount].x(), 768 vertex[edgeCount].y(), 880 vertex[edgeCount].y(), 769 vertex[edgeCount].z()); 881 vertex[edgeCount].z()); >> 882 #else >> 883 fOglVertex.push_back(vertex[edgeCount].x()); >> 884 fOglVertex.push_back(vertex[edgeCount].y()); >> 885 fOglVertex.push_back(vertex[edgeCount].z()); >> 886 >> 887 fOglVertex.push_back(normals[edgeCount].x()); >> 888 fOglVertex.push_back(normals[edgeCount].y()); >> 889 fOglVertex.push_back(normals[edgeCount].z()); >> 890 >> 891 #endif 770 } 892 } >> 893 #ifndef G4OPENGL_VERSION_2 771 glEnd (); 894 glEnd (); >> 895 #else >> 896 glEndVBO(); >> 897 #endif 772 end_of_drawing_through_stencil: 898 end_of_drawing_through_stencil: 773 899 774 // and once more to reset the stencil bi 900 // and once more to reset the stencil bits... 775 glStencilFunc (GL_ALWAYS, 0, 1); 901 glStencilFunc (GL_ALWAYS, 0, 1); 776 glStencilOp (GL_INVERT, GL_INVERT, GL_IN 902 glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT); 777 glDepthFunc (GL_LEQUAL); // to make sur 903 glDepthFunc (GL_LEQUAL); // to make sure line gets drawn. 778 if (isTransparent) { 904 if (isTransparent) { 779 // Transparent... 905 // Transparent... 780 //glDisable (GL_CULL_FACE); << 906 glDisable (GL_CULL_FACE); 781 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 907 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 782 } else { 908 } else { 783 // Opaque... 909 // Opaque... 784 if (clipping) { 910 if (clipping) { 785 //glDisable (GL_CULL_FACE); << 911 glDisable (GL_CULL_FACE); 786 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE) 912 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 787 } else { 913 } else { 788 //glEnable (GL_CULL_FACE); << 914 glEnable (GL_CULL_FACE); 789 //glCullFace (GL_BACK); << 915 glCullFace (GL_BACK); 790 glPolygonMode (GL_FRONT, GL_LINE); 916 glPolygonMode (GL_FRONT, GL_LINE); 791 } 917 } 792 } 918 } 793 glDisable (GL_LIGHTING); 919 glDisable (GL_LIGHTING); 794 glColor4fv (current_colour); 920 glColor4fv (current_colour); 795 fEdgeFlag = true; 921 fEdgeFlag = true; >> 922 #ifndef G4OPENGL_VERSION_2 796 glBegin (GL_QUADS); 923 glBegin (GL_QUADS); 797 glEdgeFlag (GL_TRUE); 924 glEdgeFlag (GL_TRUE); 798 fEdgeFlag = true; 925 fEdgeFlag = true; >> 926 #else >> 927 fEmulate_GL_QUADS = true; >> 928 glBeginVBO(GL_TRIANGLE_STRIP); >> 929 #endif 799 for (int edgeCount = 0; edgeCount < 4; + 930 for (int edgeCount = 0; edgeCount < 4; ++edgeCount) { >> 931 #ifndef G4OPENGL_VERSION_2 800 if (edgeFlag[edgeCount] > 0) { 932 if (edgeFlag[edgeCount] > 0) { 801 if (fEdgeFlag != true) { 933 if (fEdgeFlag != true) { 802 glEdgeFlag (GL_TRUE); 934 glEdgeFlag (GL_TRUE); 803 fEdgeFlag = true; 935 fEdgeFlag = true; 804 } 936 } 805 } else { 937 } else { 806 if (fEdgeFlag != false) { 938 if (fEdgeFlag != false) { 807 glEdgeFlag (GL_FALSE); 939 glEdgeFlag (GL_FALSE); 808 fEdgeFlag = false; 940 fEdgeFlag = false; 809 } 941 } 810 } 942 } 811 glNormal3d (normals[edgeCount].x(), 943 glNormal3d (normals[edgeCount].x(), 812 normals[edgeCount].y(), 944 normals[edgeCount].y(), 813 normals[edgeCount].z()); 945 normals[edgeCount].z()); 814 glVertex3d (vertex[edgeCount].x(), 946 glVertex3d (vertex[edgeCount].x(), 815 vertex[edgeCount].y(), 947 vertex[edgeCount].y(), 816 vertex[edgeCount].z()); 948 vertex[edgeCount].z()); >> 949 #else >> 950 fOglVertex.push_back(vertex[edgeCount].x()); >> 951 fOglVertex.push_back(vertex[edgeCount].y()); >> 952 fOglVertex.push_back(vertex[edgeCount].z()); >> 953 >> 954 fOglVertex.push_back(normals[edgeCount].x()); >> 955 fOglVertex.push_back(normals[edgeCount].y()); >> 956 fOglVertex.push_back(normals[edgeCount].z()); >> 957 >> 958 #endif 817 } 959 } >> 960 #ifndef G4OPENGL_VERSION_2 818 glEnd (); 961 glEnd (); >> 962 #else >> 963 glEndVBO(); >> 964 #endif 819 965 820 glDepthFunc (GL_LEQUAL); // Revert for 966 glDepthFunc (GL_LEQUAL); // Revert for next facet. 821 fEdgeFlag = true; 967 fEdgeFlag = true; >> 968 #ifndef G4OPENGL_VERSION_2 822 glBegin (GL_QUADS); // Ready for ne 969 glBegin (GL_QUADS); // Ready for next facet. GL 823 glEdgeFlag (GL_TRUE); 970 glEdgeFlag (GL_TRUE); 824 fEdgeFlag = true; 971 fEdgeFlag = true; 825 // says it ignores incomplete 972 // says it ignores incomplete 826 // quadrilaterals, so final empty 973 // quadrilaterals, so final empty 827 // glBegin/End sequence should be OK. 974 // glBegin/End sequence should be OK. >> 975 #else >> 976 fEmulate_GL_QUADS = true; >> 977 glBeginVBO(GL_TRIANGLE_STRIP); >> 978 #endif 828 } 979 } 829 } while (notLastFace); 980 } while (notLastFace); 830 981 >> 982 #ifndef G4OPENGL_VERSION_2 831 glEnd (); 983 glEnd (); >> 984 #else >> 985 >> 986 // FIXME: du grand n'importe quoi en test >> 987 // Cube optimization >> 988 >> 989 // store old DrawType because in case of optimization it could be changed >> 990 GLenum oldDrawArrayType = fDrawArrayType; >> 991 >> 992 if (dynamic_cast<const G4PolyhedronTrd2*>(&polyhedron)) { >> 993 // OptimizeVBOForTrd(); >> 994 } else if (dynamic_cast<const G4PolyhedronCons*>(&polyhedron)) { >> 995 // OptimizeVBOForCons((polyhedron.GetNoVertices()-2)/2 ); // top + bottom + all faces >> 996 } >> 997 >> 998 glEndVBO(); >> 999 fDrawArrayType = oldDrawArrayType; >> 1000 #endif >> 1001 832 glDisable (GL_STENCIL_TEST); // Revert to d 1002 glDisable (GL_STENCIL_TEST); // Revert to default for next primitive. 833 glDepthMask (GL_TRUE); // Revert to d 1003 glDepthMask (GL_TRUE); // Revert to default for next primitive. >> 1004 #ifndef G4OPENGL_VERSION_2 834 glDisable (GL_LIGHTING); // Revert to d 1005 glDisable (GL_LIGHTING); // Revert to default for next primitive. >> 1006 #endif 835 } 1007 } 836 1008 837 void G4OpenGLSceneHandler::AddCompound(const G 1009 void G4OpenGLSceneHandler::AddCompound(const G4VTrajectory& traj) { 838 G4VSceneHandler::AddCompound(traj); // For 1010 G4VSceneHandler::AddCompound(traj); // For now. 839 } 1011 } 840 1012 841 void G4OpenGLSceneHandler::AddCompound(const G 1013 void G4OpenGLSceneHandler::AddCompound(const G4VHit& hit) { 842 G4VSceneHandler::AddCompound(hit); // For n 1014 G4VSceneHandler::AddCompound(hit); // For now. 843 } 1015 } 844 1016 845 void G4OpenGLSceneHandler::AddCompound(const G 1017 void G4OpenGLSceneHandler::AddCompound(const G4VDigi& digi) { 846 G4VSceneHandler::AddCompound(digi); // For 1018 G4VSceneHandler::AddCompound(digi); // For now. 847 } 1019 } 848 1020 849 void G4OpenGLSceneHandler::AddCompound(const G 1021 void G4OpenGLSceneHandler::AddCompound(const G4THitsMap<G4double>& hits) { 850 G4VSceneHandler::AddCompound(hits); // For 1022 G4VSceneHandler::AddCompound(hits); // For now. 851 } 1023 } 852 1024 853 void G4OpenGLSceneHandler::AddCompound(const G 1025 void G4OpenGLSceneHandler::AddCompound(const G4THitsMap<G4StatDouble>& hits) { 854 G4VSceneHandler::AddCompound(hits); // For 1026 G4VSceneHandler::AddCompound(hits); // For now. 855 } 1027 } 856 1028 857 void G4OpenGLSceneHandler::AddCompound(const G << 1029 858 StandardSpecialMeshRendering(mesh); << 1030 #ifdef G4OPENGL_VERSION_2 >> 1031 >> 1032 // Optimize vertex and indices in order to render less vertex in OpenGL VBO/IBO >> 1033 void G4OpenGLSceneHandler::OptimizeVBOForTrd(){ >> 1034 >> 1035 /* HOW IT IS BUILD (as we receive it from fOglVertex : >> 1036 */ >> 1037 >> 1038 std::vector<double> vertices; >> 1039 vertices.insert (vertices.end(),fOglVertex.begin(),fOglVertex.begin()+6*6); // ABCDEF >> 1040 vertices.insert (vertices.end(),fOglVertex.begin()+9*6,fOglVertex.begin()+9*6+6); // G >> 1041 vertices.insert (vertices.end(),fOglVertex.begin()+13*6,fOglVertex.begin()+13*6+6); // H >> 1042 fOglVertex = vertices; >> 1043 >> 1044 int myarray [] = { >> 1045 3,2,0,1,4,5,7,6, 6,0,4,3,7,2,6,1,5 >> 1046 }; >> 1047 fOglIndices.insert(fOglIndices.begin(), myarray, myarray+17/*36*/); >> 1048 >> 1049 fDrawArrayType = GL_TRIANGLE_STRIP; >> 1050 } >> 1051 >> 1052 // Optimize vertex and indices in order to render less vertex in OpenGL VBO/IBO >> 1053 void G4OpenGLSceneHandler::OptimizeVBOForCons(G4int aNoFaces){ >> 1054 // Optimized, 1st level : 10f/15sec with 1000 cones >> 1055 // DrawElements:208 vertex and 605 (2*100+2*100+2*100+5) indices for a 100 face cone >> 1056 >> 1057 /* surface of polycone : could be optimized >> 1058 for 100 faces : >> 1059 - 100*4 = 400 points >> 1060 - 100*2+2 = 202 points with TRIANGLE_STRIP >> 1061 Total : >> 1062 n*4+n*4+n*4 = n*12 >> 1063 optimize : n*2+2+1+n+1 = n*3+3 (factor 4) >> 1064 but could do better : n faces should give = n*2+2 >> 1065 */ >> 1066 >> 1067 /* >> 1068 0 >> 1069 / \ >> 1070 2---4 6 ....2 >> 1071 | | >> 1072 3---5 7 ....3 >> 1073 \ / >> 1074 1 >> 1075 */ >> 1076 // First, faces >> 1077 std::vector<double> vertices; >> 1078 >> 1079 // Add bottom and top vertex >> 1080 // aNoFaces*4*6+6 : nb Faces * 4 points per face * 6 vertex by point + 1 point offset >> 1081 vertices.insert (vertices.end(),fOglVertex.begin()+ (aNoFaces*4)*6,fOglVertex.begin()+(aNoFaces*4)*6+6); // 0 >> 1082 vertices.insert (vertices.end(),fOglVertex.begin()+ (aNoFaces*8+1)*6,fOglVertex.begin()+(aNoFaces*8+1)*6+6); // 1 >> 1083 >> 1084 // Add facets points >> 1085 G4int posInVertice; >> 1086 for (G4int a = 0; a<aNoFaces; a++) { >> 1087 posInVertice = a*4*6; >> 1088 vertices.insert (vertices.end(),fOglVertex.begin()+posInVertice,fOglVertex.begin()+posInVertice+1*6+6); // AB >> 1089 } >> 1090 vertices.insert (vertices.end(),fOglVertex.begin(),fOglVertex.begin()+1*6*6); // AB >> 1091 fOglVertex = vertices; >> 1092 >> 1093 // Add indices for top : >> 1094 // simple version : 0-2-0-4-0-6-0-8-0-10.. >> 1095 // optimized version : 2-0-4-6- 6-0-8-10.. but we have to deal with odd faces numbers >> 1096 for (G4int a=0; a<aNoFaces; a++) { >> 1097 fOglIndices.push_back(0); >> 1098 fOglIndices.push_back(a*2+2); >> 1099 } >> 1100 // close strip >> 1101 fOglIndices.push_back(0); >> 1102 fOglIndices.push_back(2); >> 1103 >> 1104 // Add indices for faces >> 1105 for (G4int a = 0; a<aNoFaces; a++) { >> 1106 fOglIndices.push_back(a*2+2); >> 1107 fOglIndices.push_back(a*2+1+2); >> 1108 } >> 1109 fOglIndices.push_back(2); >> 1110 fOglIndices.push_back(2+1); >> 1111 >> 1112 // Second : top >> 1113 // 3-1-5-1-7-1-9-1.. >> 1114 for (G4int a=0; a<aNoFaces; a++) { >> 1115 fOglIndices.push_back(a*2+3); >> 1116 fOglIndices.push_back(1); >> 1117 } >> 1118 // close strip >> 1119 fOglIndices.push_back(0+3); >> 1120 >> 1121 fDrawArrayType = GL_TRIANGLE_STRIP; >> 1122 fEmulate_GL_QUADS = false; >> 1123 } >> 1124 >> 1125 void G4OpenGLSceneHandler::glBeginVBO(GLenum type) { >> 1126 fDrawArrayType = type; >> 1127 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER >> 1128 glGenBuffers(1,&fVertexBufferObject); >> 1129 glGenBuffers(1,&fIndicesBufferObject); >> 1130 #else >> 1131 fVertexBufferObject = glCreateBuffer(); //glGenBuffer(1,fVertexBufferObject_2) >> 1132 fIndicesBufferObject = glCreateBuffer(); //glGenBuffer(1,fIndicesBufferObject_2) >> 1133 #endif >> 1134 >> 1135 // clear data and indices for OpenGL >> 1136 fOglVertex.clear(); >> 1137 fOglIndices.clear(); >> 1138 } >> 1139 >> 1140 // 2 cases : >> 1141 /* >> 1142 glDrawArray : if there is no vertex indices : fOglIndices.size() == 0 >> 1143 glDrawElements : if there is vertex indices : fOglIndices.size() != 0 >> 1144 >> 1145 */ >> 1146 void G4OpenGLSceneHandler::glEndVBO() { >> 1147 if (fOglIndices.size() == 0) { >> 1148 >> 1149 >> 1150 std::vector<double> vertices; >> 1151 // check if it is a GL_QUADS emulation >> 1152 if (fEmulate_GL_QUADS == true) { >> 1153 fEmulate_GL_QUADS = false; >> 1154 // A point has 6 double : Vx Vy Vz Nx Ny Nz >> 1155 // A QUAD should be like this >> 1156 /* >> 1157 0 3/4 7/8 .. >> 1158 >> 1159 1 2/5 6/9 .. >> 1160 */ >> 1161 // And if 3==4 and 2==5, we should do it like this for a TRIANGLES_STRIP >> 1162 /* >> 1163 0 4 8 .. >> 1164 | / | / | >> 1165 1 5 9 .. >> 1166 // Optimized, 1st level : 24f/15sec with 10 cones >> 1167 // non Optimized, 1st level : 12f/15sec with 10 cones >> 1168 */ >> 1169 // should be 4 points >> 1170 for (unsigned int a=0; a<fOglVertex.size(); a+=6*4) { >> 1171 vertices.insert (vertices.end(),fOglVertex.begin()+a,fOglVertex.begin()+a+1*6+6); // 0-1 >> 1172 // if 2-3 == 4-5, do not add them >> 1173 // if differents, we are obliged to create a new GL_TRIANGLE_STRIP >> 1174 if (a+4*6+5 < fOglVertex.size()) { >> 1175 if ((fOglVertex[a+2*6+0] != fOglVertex[a+5*6+0]) || //Vx for 2 and 5 >> 1176 (fOglVertex[a+2*6+1] != fOglVertex[a+5*6+1]) || //Vy for 2 and 5 >> 1177 (fOglVertex[a+2*6+2] != fOglVertex[a+5*6+2]) || //Vz for 2 and 5 >> 1178 (fOglVertex[a+2*6+3] != fOglVertex[a+5*6+3]) || //Px for 2 and 5 >> 1179 (fOglVertex[a+2*6+4] != fOglVertex[a+5*6+4]) || //Py for 2 and 5 >> 1180 (fOglVertex[a+2*6+5] != fOglVertex[a+5*6+5]) || //Pz for 2 and 5 >> 1181 >> 1182 (fOglVertex[a+3*6+0] != fOglVertex[a+4*6+0]) || //Vx for 3 and 4 >> 1183 (fOglVertex[a+3*6+1] != fOglVertex[a+4*6+1]) || //Vy for 3 and 4 >> 1184 (fOglVertex[a+3*6+2] != fOglVertex[a+4*6+2]) || //Vz for 3 and 4 >> 1185 (fOglVertex[a+3*6+3] != fOglVertex[a+4*6+3]) || //Px for 3 and 4 >> 1186 (fOglVertex[a+3*6+4] != fOglVertex[a+4*6+4]) || //Py for 3 and 4 >> 1187 (fOglVertex[a+3*6+5] != fOglVertex[a+4*6+5])) { //Pz for 3 and 4 >> 1188 // add last points >> 1189 vertices.insert (vertices.end(),fOglVertex.begin()+a+3*6,fOglVertex.begin()+a+3*6+6); // 3 >> 1190 vertices.insert (vertices.end(),fOglVertex.begin()+a+2*6,fOglVertex.begin()+a+2*6+6); // 2 >> 1191 // build and send the GL_TRIANGLE_STRIP >> 1192 drawVBOArray(vertices); >> 1193 vertices.clear(); >> 1194 } >> 1195 } else { // end of volume >> 1196 vertices.insert (vertices.end(),fOglVertex.begin()+a+3*6,fOglVertex.begin()+a+3*6+6); // 3 >> 1197 vertices.insert (vertices.end(),fOglVertex.begin()+a+2*6,fOglVertex.begin()+a+2*6+6); // 2 >> 1198 } >> 1199 } >> 1200 fOglVertex = vertices; >> 1201 } >> 1202 >> 1203 drawVBOArray(fOglVertex); >> 1204 >> 1205 } else { >> 1206 >> 1207 // Bind VBO >> 1208 glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject); >> 1209 >> 1210 // Load fOglVertex into VBO >> 1211 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER >> 1212 int sizeV = fOglVertex.size(); >> 1213 // FIXME : perhaps a problem withBufferData in OpenGL other than WebGL ? >> 1214 // void glBufferData( GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); >> 1215 glBufferData(GL_ARRAY_BUFFER, sizeof(double)*sizeV, &fOglVertex[0], GL_STATIC_DRAW); >> 1216 #else >> 1217 glBufferDatafv(GL_ARRAY_BUFFER, fOglVertex.begin(), fOglVertex.end(), GL_STATIC_DRAW); >> 1218 #endif >> 1219 >> 1220 // Bind IBO >> 1221 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fIndicesBufferObject); >> 1222 >> 1223 // Load fOglVertex into VBO >> 1224 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER >> 1225 int sizeI = fOglIndices.size(); >> 1226 glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(int)*sizeI, &fOglIndices[0], GL_STATIC_DRAW); >> 1227 #else >> 1228 glBufferDataiv(GL_ELEMENT_ARRAY_BUFFER, fOglIndices.begin(), fOglIndices.end(), GL_STATIC_DRAW, GL_UNSIGNED_BYTE); >> 1229 #endif >> 1230 >> 1231 //---------------------------- >> 1232 // Draw VBO >> 1233 //---------------------------- >> 1234 glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject); >> 1235 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fIndicesBufferObject); >> 1236 >> 1237 // the fVertexPositionAttribute is inside the G4OpenGLViewer >> 1238 G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer); >> 1239 if (pGLViewer) { >> 1240 glEnableVertexAttribArray(pGLViewer->fVertexPositionAttribute); >> 1241 >> 1242 glVertexAttribPointer(pGLViewer->fVertexPositionAttribute, >> 1243 3, // size: Every vertex has an X, Y anc Z component >> 1244 GL_FLOAT, // type: They are floats >> 1245 GL_FALSE, // normalized: Please, do NOT normalize the vertices >> 1246 2*3*4, // stride: The first byte of the next vertex is located this >> 1247 // amount of bytes further. The format of the VBO is >> 1248 // vx, vy, vz, nx, ny, nz and every element is a >> 1249 // Float32, hence 4 bytes large >> 1250 0); // offset: The byte position of the first vertex in the buffer >> 1251 } >> 1252 >> 1253 >> 1254 glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject); >> 1255 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fIndicesBufferObject); >> 1256 // glDrawElements(fDrawArrayType, fOglIndices.size(), GL_UNSIGNED_SHORT, 0); >> 1257 glDrawElements(fDrawArrayType, fOglIndices.size(), GL_UNSIGNED_SHORT, 0); >> 1258 >> 1259 if (pGLViewer) { >> 1260 glDisableVertexAttribArray(pGLViewer->fVertexPositionAttribute); >> 1261 } >> 1262 >> 1263 // delete the buffer >> 1264 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER >> 1265 glDeleteBuffers(1,&fVertexBufferObject); >> 1266 #else >> 1267 glDeleteBuffer(fVertexBufferObject); >> 1268 #endif >> 1269 } >> 1270 } >> 1271 >> 1272 void G4OpenGLSceneHandler::drawVBOArray(std::vector<double> vertices) { >> 1273 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER >> 1274 glGenBuffers(1,&fVertexBufferObject); >> 1275 glGenBuffers(1,&fIndicesBufferObject); >> 1276 #else >> 1277 fVertexBufferObject = glCreateBuffer(); //glGenBuffer(1,fVertexBufferObject_2) >> 1278 fIndicesBufferObject = glCreateBuffer(); //glGenBuffer(1,fIndicesBufferObject_2) >> 1279 #endif >> 1280 >> 1281 // Bind this buffer >> 1282 glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject); >> 1283 // Load oglData into VBO >> 1284 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER >> 1285 int s = vertices.size(); >> 1286 glBufferData(GL_ARRAY_BUFFER, sizeof(double)*s, &vertices[0], GL_STATIC_DRAW); >> 1287 #else >> 1288 glBufferDatafv(GL_ARRAY_BUFFER, vertices.begin(), vertices.end(), GL_STATIC_DRAW); >> 1289 #endif >> 1290 >> 1291 //---------------------------- >> 1292 // Draw VBO >> 1293 //---------------------------- >> 1294 glBindBuffer(GL_ARRAY_BUFFER, fVertexBufferObject); >> 1295 >> 1296 // the fVertexPositionAttribute is inside the G4OpenGLViewer >> 1297 G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer); >> 1298 if (pGLViewer) { >> 1299 glEnableVertexAttribArray(pGLViewer->fVertexPositionAttribute); >> 1300 >> 1301 // glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) >> 1302 >> 1303 /* >> 1304 GL_DOUBLE >> 1305 Warning: This section describes legacy OpenGL APIs that have been removed from core OpenGL 3.1 and above (they are only deprecated in OpenGL 3.0). It is recommended that you not use this functionality in your programs. >> 1306 >> 1307 glLoadMatrixd, glRotated and any other function that have to do with the double type. Most GPUs don't support GL_DOUBLE (double) so the driver will convert the data to GL_FLOAT (float) and send to the GPU. If you put GL_DOUBLE data in a VBO, the performance might even be much worst than immediate mode (immediate mode means glBegin, glVertex, glEnd). GL doesn't offer any better way to know what the GPU prefers. >> 1308 */ >> 1309 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER >> 1310 glVertexAttribPointer(pGLViewer->fVertexPositionAttribute, >> 1311 3, // size: Every vertex has an X, Y anc Z component >> 1312 GL_DOUBLE, // type: They are double >> 1313 GL_FALSE, // normalized: Please, do NOT normalize the vertices >> 1314 6*sizeof(double), // stride: The first byte of the next vertex is located this >> 1315 // amount of bytes further. The format of the VBO is >> 1316 // vx, vy, vz, nx, ny, nz and every element is a >> 1317 // Float32, hence 4 bytes large >> 1318 0); // offset: The byte position of the first vertex in the buffer >> 1319 #else >> 1320 glVertexAttribPointer(pGLViewer->fVertexPositionAttribute, >> 1321 3, // size: Every vertex has an X, Y anc Z component >> 1322 GL_FLOAT, // type: They are floats >> 1323 GL_FALSE, // normalized: Please, do NOT normalize the vertices >> 1324 2*3*4, // stride: The first byte of the next vertex is located this >> 1325 // amount of bytes further. The format of the VBO is >> 1326 // vx, vy, vz, nx, ny, nz and every element is a >> 1327 // Float32, hence 4 bytes large >> 1328 0); // offset: The byte position of the first vertex in the buffer >> 1329 #endif >> 1330 } >> 1331 >> 1332 glDrawArrays(fDrawArrayType, // GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP, and GL_TRIANGLES >> 1333 0, vertices.size()/6); >> 1334 if (pGLViewer) { >> 1335 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER >> 1336 glDisableClientState( GL_VERTEX_ARRAY ); >> 1337 #else >> 1338 glDisableVertexAttribArray(pGLViewer->fVertexPositionAttribute); >> 1339 #endif >> 1340 } >> 1341 >> 1342 // delete the buffer >> 1343 #ifndef G4VIS_BUILD_OPENGLWT_DRIVER >> 1344 glDeleteBuffers(1,&fVertexBufferObject); >> 1345 #else >> 1346 glDeleteBuffer(fVertexBufferObject); >> 1347 #endif 859 } 1348 } >> 1349 #endif >> 1350 >> 1351 #endif 860 1352