Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** 25 // 22 // 26 // 23 // >> 24 // $Id: G4OpenGLSceneHandler.cc,v 1.18 2003/06/10 17:13:33 gcosmo Exp $ >> 25 // GEANT4 tag $Name: geant4-05-02 $ 27 // 26 // 28 // << 27 // 29 // Andrew Walkden 27th March 1996 28 // Andrew Walkden 27th March 1996 30 // OpenGL stored scene - creates OpenGL displa 29 // OpenGL stored scene - creates OpenGL display lists. 31 // OpenGL immediate scene - draws immediately 30 // OpenGL immediate scene - draws immediately to buffer 32 // (saving space on 31 // (saving space on server). 33 32 >> 33 #ifdef G4VIS_BUILD_OPENGL_DRIVER >> 34 >> 35 // Included here - problems with HP compiler if not before other includes? >> 36 #include "G4NURBS.hh" 34 37 35 # include "G4OpenGLSceneHandler.hh" << 38 // Here follows a special for Mesa, the OpenGL emulator. Does not affect 36 # include "G4OpenGLViewer.hh" << 39 // other OpenGL's, as far as I'm aware. John Allison 18/9/96. 37 # include "G4OpenGLTransform3D.hh" << 40 #define CENTERLINE_CLPP /* CenterLine C++ workaround: */ 38 # include "G4Point3D.hh" << 41 // Also seems to be required for HP's CC and AIX xlC, at least. 39 # include "G4Normal3D.hh" << 42 40 # include "G4Transform3D.hh" << 43 #include "G4OpenGLSceneHandler.hh" 41 # include "G4Polyline.hh" << 44 #include "G4OpenGLViewer.hh" 42 # include "G4Polymarker.hh" << 45 #include "G4OpenGLTransform3D.hh" 43 # include "G4Text.hh" << 46 #include "G4Point3D.hh" 44 # include "G4Circle.hh" << 47 #include "G4Normal3D.hh" 45 # include "G4Square.hh" << 48 #include "G4Transform3D.hh" 46 # include "G4VMarker.hh" << 49 #include "G4Polyline.hh" 47 # include "G4Polyhedron.hh" << 50 #include "G4Text.hh" 48 # include "G4VisAttributes.hh" << 51 #include "G4Circle.hh" 49 # include "G4PhysicalVolumeModel.hh" << 52 #include "G4Square.hh" 50 # include "G4VPhysicalVolume.hh" << 53 #include "G4VMarker.hh" 51 # include "G4LogicalVolume.hh" << 54 #include "G4Polyhedron.hh" 52 # include "G4VSolid.hh" << 55 #include "G4VisAttributes.hh" 53 # include "G4Scene.hh" << 56 54 # include "G4VisExtent.hh" << 57 G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4VGraphicsSystem& system, 55 # include "G4AttHolder.hh" << 58 G4int id, 56 # include "G4PhysicalConstants.hh" << 59 const G4String& name): 57 # include "G4RunManager.hh" << 60 G4VSceneHandler (system, id, name) 58 # include "G4Run.hh" << 61 { 59 # include "G4RunManagerFactory.hh" << 62 initialize_hlr = true; 60 # include "G4Mesh.hh" << 63 // glPolygonOffset (1.0, 2); 61 # include "G4PseudoScene.hh" << 64 } 62 # include "G4VisManager.hh" << 65 >> 66 G4OpenGLSceneHandler::~G4OpenGLSceneHandler () >> 67 { >> 68 ClearStore (); >> 69 } 63 70 64 const GLubyte G4OpenGLSceneHandler::fStippleMa 71 const GLubyte G4OpenGLSceneHandler::fStippleMaskHashed [128] = { 65 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 72 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 66 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 73 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 67 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 74 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 68 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 75 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 69 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 76 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 70 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 77 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 71 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 78 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 72 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 79 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 73 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 80 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 74 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 81 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 75 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 82 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 76 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 83 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 77 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 84 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 78 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 85 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 79 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 86 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 80 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55 87 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55 81 }; 88 }; 82 89 83 G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4 << 90 //Method for handling G4Polyline objects (from tracking or wireframe). 84 G4 << 85 co << 86 G4VSceneHandler (system, id, name), << 87 fPickName(0), << 88 fThreePassCapable(false), << 89 fSecondPassForTransparencyRequested(false), << 90 fSecondPassForTransparency(false), << 91 fThirdPassForNonHiddenMarkersRequested(false), << 92 fThirdPassForNonHiddenMarkers(false), << 93 fEdgeFlag(true) << 94 { << 95 } << 96 << 97 G4OpenGLSceneHandler::~G4OpenGLSceneHandler () << 98 { << 99 ClearStore (); << 100 } << 101 << 102 void G4OpenGLSceneHandler::ClearAndDestroyAtts << 103 { << 104 std::map<GLuint, G4AttHolder*>::iterator i; << 105 for (i = fPickMap.begin(); i != fPickMap.end << 106 fPickMap.clear(); << 107 } << 108 << 109 G4int G4OpenGLSceneHandler::fEntitiesFlushInte << 110 G4OpenGLSceneHandler::FlushAction << 111 G4OpenGLSceneHandler::fFlushAction = G4OpenGLS << 112 << 113 void G4OpenGLSceneHandler::ScaledFlush() << 114 { << 115 if (fReadyForTransients) { << 116 << 117 // Drawing transients, e.g., trajectories. << 118 << 119 if (!fpScene) { << 120 // No scene - shouldn't happen << 121 glFlush(); << 122 return; << 123 } << 124 // Get event from modeling parameters << 125 if (!fpModel) { << 126 // No model - shouldn't happen << 127 glFlush(); << 128 return; << 129 } << 130 const G4ModelingParameters* modelingParame << 131 fpModel->GetModelingParameters(); << 132 if (!modelingParameters) { << 133 // No modeling parameters - shouldn't ha << 134 glFlush(); << 135 return; << 136 } << 137 const G4Event* thisEvent = modelingParamet << 138 if (!thisEvent) { << 139 // No event, so not in event loop. << 140 if (fFlushAction == endOfEvent) { << 141 fFlushAction = endOfRun; << 142 } else if (fFlushAction == NthEvent) { << 143 fFlushAction = NthPrimitive; << 144 } << 145 } << 146 G4RunManager* runMan = G4RunManagerFactory << 147 if (!runMan) { << 148 // No run manager - shouldn't happen << 149 glFlush(); << 150 return; << 151 } << 152 const G4Run* thisRun = runMan->GetCurrentR << 153 if (!thisRun) { << 154 // No run, so not in event loop. << 155 if (fFlushAction == endOfRun) { << 156 fFlushAction = NthPrimitive; << 157 } else if (fFlushAction == NthEvent) { << 158 fFlushAction = NthPrimitive; << 159 } << 160 } << 161 << 162 switch (fFlushAction) { << 163 case endOfEvent: << 164 // If "/vis/scene/endOfEventAction ref << 165 // end of run anyway, so only scale if << 166 if (!fpScene->GetRefreshAtEndOfEvent() << 167 // But if "/vis/scene/endOfEventActi << 168 // called until end of run, so we ha << 169 // Get event from modeling parameter << 170 G4int thisEventID = thisEvent->GetEv << 171 static G4int lastEventID = 0; << 172 if (thisEventID != lastEventID) { << 173 glFlush(); << 174 lastEventID = thisEventID; << 175 } << 176 } << 177 break; << 178 case endOfRun: << 179 // If "/vis/scene/endOfRunAction refre << 180 // end of run anyway, so only scale if << 181 if (!fpScene->GetRefreshAtEndOfRun()) << 182 // If "/vis/scene/endOfRunAction acc << 183 // so we have to watch for a new run << 184 G4int thisRunID = thisRun->GetRunID( << 185 static G4int lastRunID = 0; << 186 if (thisRunID != lastRunID) { << 187 glFlush(); << 188 lastRunID = thisRunID; << 189 } << 190 } << 191 break; << 192 case eachPrimitive: << 193 // This is equivalent to numeric with << 194 fEntitiesFlushInterval = 1; << 195 [[fallthrough]]; // Fall through to NthPrim << 196 case NthPrimitive: << 197 { // Encapsulate in scope {} brackets to << 198 static G4int primitivesWaitingToBeFlus << 199 primitivesWaitingToBeFlushed++; << 200 if (primitivesWaitingToBeFlushed < fEn << 201 glFlush(); << 202 primitivesWaitingToBeFlushed = 0; << 203 break; << 204 } << 205 case NthEvent: << 206 // If "/vis/scene/endOfEventAction ref << 207 // end of event anyway, so only scale << 208 if (!fpScene->GetRefreshAtEndOfEvent() << 209 G4int thisEventID = thisEvent->GetEv << 210 static G4int lastEventID = 0; << 211 if (thisEventID != lastEventID) { << 212 static G4int eventsWaitingToBeFlus << 213 eventsWaitingToBeFlushed++; << 214 if (eventsWaitingToBeFlushed < fEn << 215 glFlush(); << 216 eventsWaitingToBeFlushed = 0; << 217 lastEventID = thisEventID; << 218 } << 219 } << 220 break; << 221 case never: << 222 break; << 223 default: << 224 break; << 225 } << 226 << 227 } << 228 << 229 else << 230 << 231 { << 232 << 233 // For run duration model drawing (detecto << 234 // Immediate mode: a huge speed up is obta << 235 // Stored mode: no discernable difference << 236 // back buffer and then swapped. << 237 // So eachPrimitive and NthPrimitive make << 238 // endOfRun are treated as "no action", i. << 239 // as happens anyway, when drawing is comp << 240 << 241 switch (fFlushAction) { << 242 case endOfEvent: << 243 break; << 244 case endOfRun: << 245 break; << 246 case eachPrimitive: << 247 // This is equivalent to NthPrimitive << 248 fEntitiesFlushInterval = 1; << 249 [[fallthrough]]; // Fall through to NthPrim << 250 case NthPrimitive: << 251 { // Encapsulate in scope {} brackets to << 252 static G4int primitivesWaitingToBeFlus << 253 primitivesWaitingToBeFlushed++; << 254 if (primitivesWaitingToBeFlushed < fEn << 255 glFlush(); << 256 primitivesWaitingToBeFlushed = 0; << 257 break; << 258 } << 259 case NthEvent: << 260 break; << 261 case never: << 262 break; << 263 default: << 264 break; << 265 } << 266 << 267 } << 268 } << 269 << 270 void G4OpenGLSceneHandler::ProcessScene() << 271 { << 272 fThreePassCapable = true; << 273 << 274 G4VSceneHandler::ProcessScene(); << 275 << 276 // Repeat if required... << 277 if (fSecondPassForTransparencyRequested) { << 278 fSecondPassForTransparency = true; << 279 G4VSceneHandler::ProcessScene(); << 280 fSecondPassForTransparency = false; << 281 fSecondPassForTransparencyRequested = fals << 282 } << 283 << 284 // And again if required... << 285 if (fThirdPassForNonHiddenMarkersRequested) << 286 fThirdPassForNonHiddenMarkers = true; << 287 G4VSceneHandler::ProcessScene(); << 288 fThirdPassForNonHiddenMarkers = false; << 289 fThirdPassForNonHiddenMarkersRequested = f << 290 } << 291 << 292 fThreePassCapable = false; << 293 } << 294 << 295 void G4OpenGLSceneHandler::PreAddSolid << 296 (const G4Transform3D& objectTransformation, << 297 const G4VisAttributes& visAttribs) << 298 { << 299 G4VSceneHandler::PreAddSolid (objectTransfor << 300 } << 301 << 302 void G4OpenGLSceneHandler::BeginPrimitives << 303 (const G4Transform3D& objectTransformation) << 304 { << 305 G4VSceneHandler::BeginPrimitives (objectTran << 306 } << 307 << 308 void G4OpenGLSceneHandler::EndPrimitives () << 309 { << 310 G4VSceneHandler::EndPrimitives (); << 311 } << 312 << 313 void G4OpenGLSceneHandler::BeginPrimitives2D << 314 (const G4Transform3D& objectTransformation) << 315 { << 316 G4VSceneHandler::BeginPrimitives2D (objectTr << 317 } << 318 << 319 void G4OpenGLSceneHandler::EndPrimitives2D () << 320 { << 321 G4VSceneHandler::EndPrimitives2D (); << 322 } << 323 << 324 G4DisplacedSolid* G4OpenGLSceneHandler::Create << 325 { << 326 return G4VSceneHandler::CreateSectionSolid() << 327 // If clipping done in G4OpenGLViewer::SetVi << 328 // return 0; << 329 // Note: if you change this, you must also c << 330 // G4OpenGLStoredViewer::CompareForKernelVis << 331 } << 332 << 333 G4DisplacedSolid* G4OpenGLSceneHandler::Create << 334 { << 335 // return G4VSceneHandler::CreateCutawaySoli << 336 // If cutaway done in G4OpenGLViewer::SetVie << 337 return 0; << 338 // Note: if you change this, you must also c << 339 // G4OpenGLStoredViewer::CompareForKernelVis << 340 } << 341 << 342 void G4OpenGLSceneHandler::AddPrimitive (const 91 void G4OpenGLSceneHandler::AddPrimitive (const G4Polyline& line) 343 { 92 { 344 std::size_t nPoints = line.size (); << 93 G4int nPoints = line.size (); 345 if (nPoints <= 0) return; 94 if (nPoints <= 0) return; 346 95 347 // Note: colour and depth test treated in su << 96 const G4Colour& c = GetColour (line); >> 97 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ()); 348 98 349 glDisable (GL_LIGHTING); << 99 if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ()) 350 << 100 glDisable (GL_DEPTH_TEST); 351 G4double lineWidth = GetLineWidth(fpVisAttri << 101 else glEnable (GL_DEPTH_TEST); 352 // Need access to method in G4OpenGLViewer. << 353 // work with a virtual base class, so use dy << 354 // test the outcome since viewer is guarante << 355 // G4OpenGLViewer, but test it anyway to kee << 356 G4OpenGLViewer* pGLViewer = dynamic_cast<G4O << 357 if (pGLViewer) pGLViewer->ChangeLineWidth(li << 358 102 359 fEdgeFlag = true; << 103 glDisable (GL_LIGHTING); 360 glBegin (GL_LINE_STRIP); 104 glBegin (GL_LINE_STRIP); 361 // No ned glEdgeFlag for lines : << 105 362 // Boundary and nonboundary edge flags on ve << 106 for (G4int iPoint = 0; iPoint < nPoints; iPoint++) { 363 << 364 // glEdgeFlag (GL_TRUE); << 365 for (std::size_t iPoint = 0; iPoint < nPoint << 366 G4double x, y, z; 107 G4double x, y, z; 367 x = line[iPoint].x(); 108 x = line[iPoint].x(); 368 y = line[iPoint].y(); 109 y = line[iPoint].y(); 369 z = line[iPoint].z(); 110 z = line[iPoint].z(); 370 glVertex3d (x, y, z); 111 glVertex3d (x, y, z); 371 } 112 } 372 glEnd (); 113 glEnd (); 373 } 114 } 374 115 375 void G4OpenGLSceneHandler::AddPrimitive (const << 116 void G4OpenGLSceneHandler::AddPrimitive (const G4Text& text) { 376 { << 377 if (polymarker.size() == 0) { << 378 return; << 379 } << 380 117 381 // Note: colour and depth test treated in su << 118 static G4int callCount (0); >> 119 ++callCount; 382 120 383 glDisable (GL_LIGHTING); << 384 << 385 MarkerSizeType sizeType; 121 MarkerSizeType sizeType; 386 G4double size = GetMarkerSize(polymarker, si << 122 G4double size = GetMarkerSize (text, sizeType); 387 << 123 G4ThreeVector position (*fpObjectTransformation * text.GetPosition ()); 388 // Need access to method in G4OpenGLViewer. << 124 if (callCount <= 10 || callCount%100 == 0) { 389 // work with a virtual base class, so use dy << 125 G4cout << 390 // test the outcome since viewer is guarante << 126 "G4OpenGLSceneHandler::AddPrimitive (const G4Text&) call count " 391 // G4OpenGLViewer, but test it anyway to kee << 127 << callCount << 392 G4OpenGLViewer* pGLViewer = dynamic_cast<G4O << 128 "\n Not implemented yet. Called with text \"" 393 if (!pGLViewer) return; << 129 << text.GetText () 394 << 130 << "\"\n at " << position 395 if (sizeType == world) { // Size specified << 131 << ", size " << size 396 G4double lineWidth = GetLineWidth(fpVisAtt << 132 << ", offsets " << text.GetXOffset () << ", " << text.GetYOffset () 397 pGLViewer->ChangeLineWidth(lineWidth); << 133 << ", type " << G4int(sizeType) 398 << 134 << G4endl; 399 G4VMarker::FillStyle style = polymarker.Ge << 400 << 401 // G4bool filled = false; Not actually us << 402 static G4bool hashedWarned = false; << 403 << 404 switch (style) { << 405 case G4VMarker::noFill: << 406 glPolygonMode (GL_FRONT_AND_BACK, GL_L << 407 glEdgeFlag (GL_TRUE); << 408 //filled = false; << 409 break; << 410 case G4VMarker::hashed: << 411 if (!hashedWarned) { << 412 G4cout << "Hashed fill style in G4Op << 413 << "\n Not implemented. Using G4VM << 414 << G4endl; << 415 hashedWarned = true; << 416 } << 417 // Maybe use << 418 //glPolygonStipple (fStippleMaskHashed << 419 [[fallthrough]]; // Drop through to filled << 420 case G4VMarker::filled: << 421 glPolygonMode (GL_FRONT_AND_BACK, GL_F << 422 //filled = true; << 423 break; << 424 } << 425 } 135 } 426 << 136 } 427 // Draw... << 428 if (sizeType == world) { // Size specified << 429 137 430 G4int nSides; << 138 void G4OpenGLSceneHandler::AddPrimitive (const G4Circle& circle) { 431 G4double startPhi; << 139 glEnable (GL_POINT_SMOOTH); 432 switch (polymarker.GetMarkerType()) { << 140 AddCircleSquare (circle, 24); 433 default: << 141 } 434 case G4Polymarker::dots: << 435 size = 1.; << 436 [[fallthrough]]; // Fall through to circles << 437 case G4Polymarker::circles: << 438 nSides = GetNoOfSides(fpVisAttribs); << 439 startPhi = 0.; << 440 break; << 441 case G4Polymarker::squares: << 442 nSides = 4; << 443 startPhi = -pi / 4.; << 444 break; << 445 } << 446 142 447 const G4Vector3D& viewpointDirection = << 143 void G4OpenGLSceneHandler::AddPrimitive (const G4Square& square) { 448 fpViewer -> GetViewParameters().GetViewp << 144 glDisable (GL_POINT_SMOOTH); 449 const G4Vector3D& up = fpViewer->GetViewPa << 145 AddCircleSquare (square, 4); 450 const G4double dPhi = twopi / nSides; << 146 } 451 const G4double radius = size / 2.; << 452 G4Vector3D start = radius * (up.cross(view << 453 G4double phi; << 454 G4int i; << 455 for (size_t iPoint = 0; iPoint < polymarke << 456 fEdgeFlag = true; << 457 glBegin (GL_POLYGON); << 458 for (i = 0, phi = startPhi; i < nSides; << 459 G4Vector3D r = start; r.rotate(phi, viewpoin << 460 G4Vector3D p = polymarker[iPoint] + r; << 461 glVertex3d (p.x(), p.y(), p.z()); << 462 } << 463 glEnd (); << 464 } << 465 147 466 } else { // Size specified in screen (window << 148 void G4OpenGLSceneHandler::AddCircleSquare >> 149 (const G4VMarker& marker, >> 150 G4int nSides) { 467 151 468 pGLViewer->ChangePointSize(size); << 152 const G4Colour& c = GetColour (marker); >> 153 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ()); >> 154 >> 155 if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ()) >> 156 glDisable (GL_DEPTH_TEST); >> 157 else glEnable (GL_DEPTH_TEST); >> 158 >> 159 glDisable (GL_LIGHTING); >> 160 >> 161 G4VMarker::FillStyle style = marker.GetFillStyle(); >> 162 >> 163 switch (style) { >> 164 case G4VMarker::noFill: >> 165 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); >> 166 break; >> 167 >> 168 case G4VMarker::hashed: >> 169 /* >> 170 G4cout << "Hashed fill style in G4OpenGLSceneHandler." >> 171 << "\n Not implemented. Using G4VMarker::filled." >> 172 << G4endl; >> 173 */ >> 174 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); >> 175 glPolygonStipple (fStippleMaskHashed); >> 176 // See also: >> 177 // if (style == G4VMarker::filled || style == G4VMarker::hashed)... >> 178 // (twice) below. >> 179 break; >> 180 >> 181 case G4VMarker::filled: >> 182 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); >> 183 break; >> 184 >> 185 default: >> 186 G4cout << "Unrecognised fill style in G4OpenGLSceneHandler." >> 187 << "\n Using G4VMarker::filled." >> 188 << G4endl; >> 189 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); >> 190 break; >> 191 >> 192 } 469 193 470 //Antialiasing only for circles << 194 // A few useful quantities... 471 switch (polymarker.GetMarkerType()) { << 195 G4Point3D centre = marker.GetPosition(); 472 default: << 196 G4bool userSpecified = (marker.GetWorldSize() || marker.GetScreenSize()); 473 case G4Polymarker::dots: << 197 const G4VMarker& def = fpViewer -> GetViewParameters().GetDefaultMarker(); 474 case G4Polymarker::circles: << 198 const G4Vector3D& viewpointDirection = 475 glEnable (GL_POINT_SMOOTH); break; << 199 fpViewer -> GetViewParameters().GetViewpointDirection(); 476 case G4Polymarker::squares: << 200 const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector(); 477 glDisable (GL_POINT_SMOOTH); break; << 201 G4double scale = fpViewer -> GetViewParameters().GetGlobalMarkerScale(); 478 } << 202 G4double size = scale * 479 glBegin (GL_POINTS); << 203 userSpecified ? marker.GetWorldSize() : def.GetWorldSize(); 480 for (size_t iPoint = 0; iPoint < polymarke << 204 481 G4Point3D centre = polymarker[iPoint]; << 205 // Find "size" of marker in world space (but see note below)... 482 glVertex3d(centre.x(),centre.y(),centre. << 206 G4double worldSize; 483 } << 207 if (size) { // Size specified in world coordinates. 484 glEnd(); << 208 worldSize = size; >> 209 } >> 210 else { // Size specified in screen (window) coordinates. >> 211 >> 212 // Find window coordinates of centre... >> 213 GLdouble modelMatrix[16]; >> 214 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix); >> 215 G4double projectionMatrix[16]; >> 216 glGetDoublev (GL_PROJECTION_MATRIX, projectionMatrix); >> 217 GLint viewport[4]; >> 218 glGetIntegerv(GL_VIEWPORT,viewport); >> 219 GLdouble winx, winy, winz; >> 220 gluProject(centre.x(), centre.y(), centre.z(), >> 221 modelMatrix, projectionMatrix, viewport, >> 222 &winx, &winy, &winz); >> 223 >> 224 // Determine ratio window:world... >> 225 const G4Vector3D inScreen = (up.cross(viewpointDirection)).unit(); >> 226 const G4Vector3D p = centre + inScreen; >> 227 GLdouble winDx, winDy, winDz; >> 228 gluProject(p.x(), p.y(), p.z(), >> 229 modelMatrix, projectionMatrix, viewport, >> 230 &winDx, &winDy, &winDz); >> 231 G4double winWorldRatio = sqrt(pow(winx - winDx, 2) + >> 232 pow(winy - winDy, 2)); >> 233 G4double winSize = scale * >> 234 userSpecified ? marker.GetScreenSize() : def.GetScreenSize(); >> 235 worldSize = winSize / winWorldRatio; 485 } 236 } 486 } << 487 237 488 void G4OpenGLSceneHandler::AddPrimitive (const << 238 // Draw... 489 // Pass to specific viewer via virtual funct << 239 DrawXYPolygon (worldSize, centre, nSides); 490 G4OpenGLViewer* pGLViewer = dynamic_cast<G4O << 491 if (pGLViewer) pGLViewer->DrawText(text); << 492 } 240 } 493 241 494 void G4OpenGLSceneHandler::AddPrimitive (const << 242 /*************************************************** 495 G4Polymarker oneCircle(circle); << 243 Note: We have to do it this way round so that when a global 496 oneCircle.push_back(circle.GetPosition()); << 244 transformation is applied, such as with /vis/viewer/set/viewpoint, 497 oneCircle.SetMarkerType(G4Polymarker::circle << 245 the markers follow the world coordinates without having to 498 // Call this AddPrimitive to avoid re-doing << 246 recreate the display lists. The down side is that the markers 499 G4OpenGLSceneHandler::AddPrimitive(oneCircle << 247 rotate. The only way to avoid this is to play with the modelview >> 248 and projection matrices of OpenGL - which I need to think about. >> 249 For future reference, here is the code to draw in window >> 250 coordinates; its down side is that markers do not follow global >> 251 transformations. Some clever stuff is needed. >> 252 >> 253 ... >> 254 // Find window coordinates of centre... >> 255 GLdouble modelMatrix[16]; >> 256 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix); >> 257 G4double projectionMatrix[16]; >> 258 glGetDoublev (GL_PROJECTION_MATRIX, projectionMatrix); >> 259 GLint viewport[4]; >> 260 glGetIntegerv(GL_VIEWPORT,viewport); >> 261 GLdouble winx, winy, winz; >> 262 gluProject(centre.x(), centre.y(), centre.z(), >> 263 modelMatrix, projectionMatrix, viewport, >> 264 &winx, &winy, &winz); >> 265 >> 266 // Find window size... >> 267 G4double winSize; >> 268 if (size) { // Size specified in world coordinates. >> 269 // Determine size in window coordinates... >> 270 (Note: improve this by using an inScreen vector as above.) >> 271 GLdouble winx1, winy1, winz1; >> 272 gluProject(centre.x() + size, centre.y() + size, centre.z() + size, >> 273 modelMatrix, projectionMatrix, viewport, >> 274 &winx1, &winy1, &winz1); >> 275 winSize = sqrt((pow(winx - winx1, 2) + >> 276 pow(winy - winy1, 2) + >> 277 pow(winz - winz1, 2)) / 3.); >> 278 } >> 279 else { >> 280 winSize = scale * >> 281 userSpecified ? marker.GetScreenSize() : def.GetScreenSize(); >> 282 } >> 283 >> 284 // Prepare to draw in window coordinates... >> 285 glMatrixMode (GL_PROJECTION); >> 286 glPushMatrix(); >> 287 glLoadIdentity(); >> 288 gluOrtho2D(GLdouble(viewport[0]), >> 289 GLdouble(viewport[0] + viewport[2]), >> 290 GLdouble(viewport[1]), >> 291 GLdouble(viewport[1] + viewport[3])); >> 292 glMatrixMode (GL_MODELVIEW); >> 293 glPushMatrix(); >> 294 glLoadIdentity(); >> 295 >> 296 // Draw in window coordinates... >> 297 DrawScreenPolygon (winSize, G4Point3D(winx, winy, winz), nSides); >> 298 >> 299 // Re-instate matrices... >> 300 glMatrixMode (GL_PROJECTION); >> 301 glPopMatrix(); >> 302 glMatrixMode (GL_MODELVIEW); >> 303 glPopMatrix(); >> 304 ... >> 305 >> 306 void G4OpenGLSceneHandler::DrawScreenPolygon >> 307 (G4double size, >> 308 const G4Point3D& centre, >> 309 G4int nSides) { >> 310 glBegin (GL_POLYGON); >> 311 const G4double dPhi = 2. * M_PI / nSides; >> 312 const G4double r = size / 2.; >> 313 G4double phi; >> 314 G4int i; >> 315 for (i = 0, phi = -dPhi / 2.; i < nSides; i++, phi += dPhi) { >> 316 G4double x, y, z; >> 317 x = centre.x() + r * cos(phi); >> 318 y = centre.y() + r * sin(phi); >> 319 z = centre.z(); >> 320 glVertex3d (x, y, z); >> 321 } >> 322 glEnd (); 500 } 323 } >> 324 **********************************************/ 501 325 502 void G4OpenGLSceneHandler::AddPrimitive (const << 326 void G4OpenGLSceneHandler::DrawXYPolygon 503 G4Polymarker oneSquare(square); << 327 (G4double size, 504 oneSquare.push_back(square.GetPosition()); << 328 const G4Point3D& centre, 505 oneSquare.SetMarkerType(G4Polymarker::square << 329 G4int nSides) { 506 // Call this AddPrimitive to avoid re-doing << 330 const G4Vector3D& viewpointDirection = 507 G4OpenGLSceneHandler::AddPrimitive(oneSquare << 331 fpViewer -> GetViewParameters().GetViewpointDirection(); >> 332 const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector(); >> 333 const G4double dPhi = 2. * M_PI / nSides; >> 334 const G4double radius = size / 2.; >> 335 G4Vector3D start = radius * (up.cross(viewpointDirection)).unit(); >> 336 G4double phi; >> 337 G4int i; >> 338 glBegin (GL_POLYGON); >> 339 for (i = 0, phi = -dPhi / 2.; i < nSides; i++, phi += dPhi) { >> 340 G4Vector3D r = start; r.rotate(phi, viewpointDirection); >> 341 G4Vector3D p = centre + r; >> 342 glVertex3d (p.x(), p.y(), p.z()); >> 343 } >> 344 glEnd (); 508 } 345 } 509 346 510 //Method for handling G4Polyhedron objects for 347 //Method for handling G4Polyhedron objects for drawing solids. 511 void G4OpenGLSceneHandler::AddPrimitive (const 348 void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) { 512 349 513 // Assume all facets are planar convex quadr << 350 //Assume all facets are convex quadrilaterals. 514 // Draw each facet individually << 351 //Draw each G4Facet individually 515 352 516 if (polyhedron.GetNoFacets() == 0) return; 353 if (polyhedron.GetNoFacets() == 0) return; 517 354 518 // Need access to data in G4OpenGLViewer. s << 355 G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (polyhedron); 519 // with a virtual base class, so use dynamic << 356 520 G4OpenGLViewer* pGLViewer = dynamic_cast<G4O << 357 //Get colour, etc.. 521 if (!pGLViewer) return; << 358 const G4Colour& c = GetColour (polyhedron); 522 << 359 523 // Get view parameters that the user can for << 524 // attributes, thereby over-riding the curre << 525 G4ViewParameters::DrawingStyle drawing_style << 526 << 527 // Note that in stored mode, because this ca << 528 // list, it is the colour _at the time of_ << 529 // even if the colour is changed, for examp << 530 // window, current_colour does not change. << 531 GLfloat* painting_colour; << 532 GLfloat clear_colour[4]; << 533 GLfloat current_colour[4]; << 534 glGetFloatv (GL_CURRENT_COLOR, current_colou << 535 << 536 G4bool isTransparent = false; << 537 if (current_colour[3] < 1.) { // This objec << 538 isTransparent = true; << 539 } << 540 << 541 if (drawing_style == G4ViewParameters::hlr) << 542 // This is the colour used to paint surfac << 543 glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_c << 544 painting_colour = clear_colour; << 545 } else { // drawing_style == G4ViewParamete << 546 painting_colour = current_colour; << 547 } << 548 << 549 G4double lineWidth = GetLineWidth(fpVisAttri << 550 pGLViewer->ChangeLineWidth(lineWidth); << 551 << 552 G4bool isAuxEdgeVisible = GetAuxEdgeVisible << 553 << 554 G4bool clipping = pGLViewer->fVP.IsSection() << 555 << 556 // Lighting disabled unless otherwise reques << 557 glDisable (GL_LIGHTING); << 558 << 559 switch (drawing_style) { 360 switch (drawing_style) { 560 case (G4ViewParameters::hlhsr): << 361 561 // Set up as for hidden line removal but p << 362 // case (G4ViewParameters::hlhsr): 562 case (G4ViewParameters::hlr): << 363 // cout << "Hidden edge not implememented in G4OpenGL.\n" 563 glEnable (GL_STENCIL_TEST); << 364 // << "Using hidden surface removal." << G4endl; 564 // The stencil buffer is cleared in G4Open << 365 565 // The procedure below leaves it clear. << 566 glStencilFunc (GL_ALWAYS, 0, 1); << 567 glStencilOp (GL_INVERT, GL_INVERT, GL_INVE << 568 glEnable (GL_DEPTH_TEST); << 569 glDepthFunc (GL_LEQUAL); << 570 if (isTransparent) { << 571 // Transparent... << 572 glColorMaterial(GL_FRONT_AND_BACK, GL_AM << 573 glEnable(GL_COLOR_MATERIAL); << 574 //glDisable (GL_CULL_FACE); << 575 glPolygonMode (GL_FRONT_AND_BACK, GL_LIN << 576 } else { << 577 // Opaque... << 578 if (clipping) { << 579 glColorMaterial(GL_FRONT_AND_BACK, GL_ << 580 glEnable(GL_COLOR_MATERIAL); << 581 //glDisable (GL_CULL_FACE); << 582 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); << 583 } else { << 584 glColorMaterial(GL_FRONT, GL_AMBIENT_A << 585 glEnable(GL_COLOR_MATERIAL); << 586 //glEnable (GL_CULL_FACE); << 587 //glCullFace (GL_BACK); << 588 glPolygonMode (GL_FRONT, GL_LINE); << 589 } << 590 } << 591 break; << 592 case (G4ViewParameters::hsr): 366 case (G4ViewParameters::hsr): 593 glEnable (GL_DEPTH_TEST); << 367 { 594 glDepthFunc (GL_LEQUAL); << 368 glPolygonMode (GL_FRONT, GL_FILL); 595 if (isTransparent) { << 369 glCullFace (GL_BACK); 596 // Transparent... << 370 //glEnable (GL_CULL_FACE); 597 glDepthMask (GL_FALSE); // Make depth b << 371 glEnable (GL_LIGHTING); 598 glColorMaterial(GL_FRONT_AND_BACK, GL_AM << 372 glEnable (GL_DEPTH_TEST); 599 glEnable(GL_COLOR_MATERIAL); << 373 GLfloat materialColour [4]; 600 //glDisable (GL_CULL_FACE); << 374 materialColour [0] = c.GetRed (); 601 glPolygonMode (GL_FRONT_AND_BACK, GL_FIL << 375 materialColour [1] = c.GetGreen (); 602 } else { << 376 materialColour [2] = c.GetBlue (); 603 // Opaque... << 377 materialColour [3] = 1.0; 604 glDepthMask (GL_TRUE); // Make depth bu << 378 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour); 605 if (clipping) { << 606 glColorMaterial(GL_FRONT_AND_BACK, GL_ << 607 glEnable(GL_COLOR_MATERIAL); << 608 //glDisable (GL_CULL_FACE); << 609 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); << 610 } else { << 611 glColorMaterial(GL_FRONT, GL_AMBIENT_A << 612 glEnable(GL_COLOR_MATERIAL); << 613 //glEnable (GL_CULL_FACE); << 614 //glCullFace (GL_BACK); << 615 glPolygonMode (GL_FRONT, GL_FILL); << 616 } << 617 } << 618 if (!fProcessing2D) glEnable (GL_LIGHTING) << 619 break; 379 break; >> 380 } >> 381 >> 382 case (G4ViewParameters::hlr): >> 383 if (initialize_hlr) { >> 384 glEnable (GL_STENCIL_TEST); >> 385 glClear (GL_STENCIL_BUFFER_BIT); >> 386 glStencilFunc (GL_ALWAYS, 0, 1); >> 387 glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT); >> 388 glGetDoublev (GL_COLOR_CLEAR_VALUE, clear_colour); >> 389 initialize_hlr = false; >> 390 // glEnable (GL_POLYGON_OFFSET_FILL); >> 391 } >> 392 glDepthFunc (GL_LESS); >> 393 //drop through to wireframe for first pass... >> 394 620 case (G4ViewParameters::wireframe): 395 case (G4ViewParameters::wireframe): >> 396 621 default: 397 default: 622 glEnable (GL_DEPTH_TEST); << 623 glDepthFunc (GL_LEQUAL); //??? was GL_A << 624 //glDisable (GL_CULL_FACE); << 625 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE) 398 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); >> 399 glDisable (GL_CULL_FACE); >> 400 glDisable (GL_LIGHTING); >> 401 glEnable (GL_DEPTH_TEST); >> 402 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ()); 626 break; 403 break; 627 } << 404 } 628 << 405 629 //Loop through all the facets... << 630 fEdgeFlag = true; << 631 glBegin (GL_QUADS); 406 glBegin (GL_QUADS); 632 glEdgeFlag (GL_TRUE); << 407 >> 408 //Loop through all the facets... 633 G4bool notLastFace; 409 G4bool notLastFace; >> 410 G4Normal3D SurfaceUnitNormal; 634 do { 411 do { 635 << 412 636 //First, find vertices, edgeflags and norm << 413 //First, find surface normal for the facet... 637 G4Point3D vertex[4]; << 414 notLastFace = polyhedron.GetNextUnitNormal (SurfaceUnitNormal); 638 G4int edgeFlag[4]; << 415 glNormal3d(SurfaceUnitNormal.x(), SurfaceUnitNormal.y(), 639 G4Normal3D normals[4]; << 416 SurfaceUnitNormal.z()); 640 G4int nEdges; << 417 641 notLastFace = polyhedron.GetNextFacet(nEdg << 642 << 643 //Loop through the four edges of each G4Fa 418 //Loop through the four edges of each G4Facet... 644 for(G4int edgeCount = 0; edgeCount < nEdge << 419 G4bool notLastEdge; >> 420 G4Point3D vertex[4]; >> 421 G4int edgeFlag[4], lastEdgeFlag (true); >> 422 edgeFlag[0] = G4int (true); >> 423 G4int edgeCount = 0; >> 424 glEdgeFlag (GL_TRUE); >> 425 do { >> 426 notLastEdge = polyhedron.GetNextVertex (vertex[edgeCount], >> 427 edgeFlag[edgeCount]); 645 // Check to see if edge is visible or no 428 // Check to see if edge is visible or not... 646 if (isAuxEdgeVisible) { << 429 if (edgeFlag[edgeCount] != lastEdgeFlag) { 647 edgeFlag[edgeCount] = 1; << 430 lastEdgeFlag = edgeFlag[edgeCount]; 648 } << 431 if (edgeFlag[edgeCount]) { 649 if (edgeFlag[edgeCount] > 0) { << 432 glEdgeFlag (GL_TRUE); 650 if (fEdgeFlag != true) { << 433 } else { 651 glEdgeFlag (GL_TRUE); << 434 glEdgeFlag (GL_FALSE); 652 fEdgeFlag = true; << 435 } 653 } << 654 } else { << 655 if (fEdgeFlag != false) { << 656 glEdgeFlag (GL_FALSE); << 657 fEdgeFlag = false; << 658 } << 659 } 436 } 660 glNormal3d (normals[edgeCount].x(), << 661 normals[edgeCount].y(), << 662 normals[edgeCount].z()); << 663 glVertex3d (vertex[edgeCount].x(), 437 glVertex3d (vertex[edgeCount].x(), 664 vertex[edgeCount].y(), 438 vertex[edgeCount].y(), 665 vertex[edgeCount].z()); 439 vertex[edgeCount].z()); 666 } << 440 edgeCount++; 667 << 441 } while (notLastEdge); 668 // HepPolyhedron produces triangles too; i << 442 while (edgeCount < 4) { // duplicate last real vertex. 669 // vertex identical to first... << 443 vertex[edgeCount] = vertex[edgeCount-1]; 670 if (nEdges == 3) { << 671 G4int edgeCount = 3; << 672 normals[edgeCount] = normals[0]; << 673 vertex[edgeCount] = vertex[0]; << 674 edgeFlag[edgeCount] = -1; << 675 if (fEdgeFlag != false) { << 676 glEdgeFlag (GL_FALSE); << 677 fEdgeFlag = false; << 678 } << 679 << 680 glNormal3d (normals[edgeCount].x(), << 681 normals[edgeCount].y(), << 682 normals[edgeCount].z()); << 683 glVertex3d (vertex[edgeCount].x(), 444 glVertex3d (vertex[edgeCount].x(), 684 vertex[edgeCount].y(), 445 vertex[edgeCount].y(), 685 vertex[edgeCount].z()); 446 vertex[edgeCount].z()); >> 447 edgeCount++; 686 } 448 } 687 // Trap situation where number of edges is << 688 if (nEdges > 4) { << 689 G4cerr << << 690 "G4OpenGLSceneHandler::AddPrimitive(G4Polyhe << 691 "\n G4Polyhedron facet with " << nEdges << << 692 } << 693 << 694 449 695 // Do it all over again (twice) for hlr... << 450 //do it all over again for hlr 2nd pass... 696 if (drawing_style == G4ViewParameters::hl << 451 if (drawing_style == G4ViewParameters::hlr) { 697 drawing_style == G4ViewParameters::hlhsr) { << 452 glEnd(); 698 << 699 glDisable(GL_COLOR_MATERIAL); // Revert << 700 glEnd (); // Placed here to balance glB << 701 453 702 // state changes below, then glBegin aga << 454 //glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, clear_colour); 703 // having glBegin/End pairs *inside* loop << 704 // usual case of no hidden line removal. << 705 << 706 // Lighting disabled unless otherwise re << 707 glDisable (GL_LIGHTING); << 708 << 709 // Draw through stencil... << 710 glStencilFunc (GL_EQUAL, 0, 1); 455 glStencilFunc (GL_EQUAL, 0, 1); 711 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); 456 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); 712 if (drawing_style == G4ViewParameters::h << 457 glPolygonMode (GL_FRONT, GL_FILL); 713 if (!fProcessing2D) glEnable (GL_LIGHTING); << 458 glColor4dv (clear_colour); 714 } << 459 edgeCount=0; 715 glEnable (GL_DEPTH_TEST); << 460 716 glDepthFunc (GL_LEQUAL); << 717 if (isTransparent) { << 718 // Transparent... << 719 glDepthMask (GL_FALSE); // Make depth buffe << 720 //glDisable (GL_CULL_FACE); << 721 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); << 722 } else { << 723 // Opaque... << 724 glDepthMask (GL_TRUE); // Make depth buffer << 725 if (clipping) { << 726 //glDisable (GL_CULL_FACE); << 727 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL) << 728 } else { << 729 //glEnable (GL_CULL_FACE); << 730 //glCullFace (GL_BACK); << 731 glPolygonMode (GL_FRONT, GL_FILL); << 732 } << 733 } << 734 if (drawing_style == G4ViewParameters:: << 735 if (isTransparent) { << 736 // Transparent - don't paint... << 737 goto end_of_drawing_through_stencil; << 738 } << 739 } << 740 if (isTransparent) { << 741 // Transparent... << 742 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_ << 743 } else { << 744 // Opaque... << 745 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFU << 746 } << 747 glColor4fv (painting_colour); << 748 glBegin (GL_QUADS); 461 glBegin (GL_QUADS); 749 glEdgeFlag (GL_TRUE); << 462 do { 750 fEdgeFlag = true; << 463 if (edgeFlag[edgeCount] != lastEdgeFlag) { 751 << 464 lastEdgeFlag = edgeFlag[edgeCount]; 752 for (int edgeCount = 0; edgeCount < 4; + << 465 if (edgeFlag[edgeCount]) { 753 if (edgeFlag[edgeCount] > 0) { << 466 glEdgeFlag (GL_TRUE); 754 if (fEdgeFlag != true) { << 467 } else { 755 glEdgeFlag (GL_TRUE); << 468 glEdgeFlag (GL_FALSE); 756 fEdgeFlag = true; << 469 } 757 } << 470 } 758 } else { << 471 glVertex3d (vertex[edgeCount].x(), 759 if (fEdgeFlag != false) { << 472 vertex[edgeCount].y(), 760 glEdgeFlag (GL_FALSE); << 473 vertex[edgeCount].z()); 761 fEdgeFlag = false; << 474 } while (++edgeCount < 4); 762 } << 475 glEnd(); 763 } << 476 764 glNormal3d (normals[edgeCount].x(), << 477 //and once more to reset the stencil bits... 765 normals[edgeCount].y(), << 766 normals[edgeCount].z()); << 767 glVertex3d (vertex[edgeCount].x(), << 768 vertex[edgeCount].y(), << 769 vertex[edgeCount].z()); << 770 } << 771 glEnd (); << 772 end_of_drawing_through_stencil: << 773 << 774 // and once more to reset the stencil bi << 775 glStencilFunc (GL_ALWAYS, 0, 1); 478 glStencilFunc (GL_ALWAYS, 0, 1); 776 glStencilOp (GL_INVERT, GL_INVERT, GL_IN 479 glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT); 777 glDepthFunc (GL_LEQUAL); // to make sur << 480 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 778 if (isTransparent) { << 481 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ()); 779 // Transparent... << 482 edgeCount=0; 780 //glDisable (GL_CULL_FACE); << 483 781 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); << 484 glBegin(GL_QUADS); 782 } else { << 485 do { 783 // Opaque... << 486 if (edgeFlag[edgeCount] != lastEdgeFlag) { 784 if (clipping) { << 487 lastEdgeFlag = edgeFlag[edgeCount]; 785 //glDisable (GL_CULL_FACE); << 488 if (edgeFlag[edgeCount]) { 786 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE) << 489 glEdgeFlag (GL_TRUE); 787 } else { << 490 } else { 788 //glEnable (GL_CULL_FACE); << 491 glEdgeFlag (GL_FALSE); 789 //glCullFace (GL_BACK); << 492 } 790 glPolygonMode (GL_FRONT, GL_LINE); << 493 } 791 } << 494 glVertex3d (vertex[edgeCount].x(), 792 } << 495 vertex[edgeCount].y(), 793 glDisable (GL_LIGHTING); << 496 vertex[edgeCount].z()); 794 glColor4fv (current_colour); << 497 } while (++edgeCount < 4); 795 fEdgeFlag = true; << 498 796 glBegin (GL_QUADS); << 499 } 797 glEdgeFlag (GL_TRUE); << 500 798 fEdgeFlag = true; << 799 for (int edgeCount = 0; edgeCount < 4; + << 800 if (edgeFlag[edgeCount] > 0) { << 801 if (fEdgeFlag != true) { << 802 glEdgeFlag (GL_TRUE); << 803 fEdgeFlag = true; << 804 } << 805 } else { << 806 if (fEdgeFlag != false) { << 807 glEdgeFlag (GL_FALSE); << 808 fEdgeFlag = false; << 809 } << 810 } << 811 glNormal3d (normals[edgeCount].x(), << 812 normals[edgeCount].y(), << 813 normals[edgeCount].z()); << 814 glVertex3d (vertex[edgeCount].x(), << 815 vertex[edgeCount].y(), << 816 vertex[edgeCount].z()); << 817 } << 818 glEnd (); << 819 << 820 glDepthFunc (GL_LEQUAL); // Revert for << 821 fEdgeFlag = true; << 822 glBegin (GL_QUADS); // Ready for ne << 823 glEdgeFlag (GL_TRUE); << 824 fEdgeFlag = true; << 825 // says it ignores incomplete << 826 // quadrilaterals, so final empty << 827 // glBegin/End sequence should be OK. << 828 } << 829 } while (notLastFace); 501 } while (notLastFace); 830 502 831 glEnd (); 503 glEnd (); 832 glDisable (GL_STENCIL_TEST); // Revert to d << 833 glDepthMask (GL_TRUE); // Revert to d << 834 glDisable (GL_LIGHTING); // Revert to d << 835 } << 836 504 837 void G4OpenGLSceneHandler::AddCompound(const G << 838 G4VSceneHandler::AddCompound(traj); // For << 839 } 505 } 840 506 841 void G4OpenGLSceneHandler::AddCompound(const G << 507 //Method for handling G4NURBS objects for drawing solids. 842 G4VSceneHandler::AddCompound(hit); // For n << 508 //Knots and Ctrl Pnts MUST be arrays of GLfloats. 843 } << 509 void G4OpenGLSceneHandler::AddPrimitive (const G4NURBS& nurb) { >> 510 >> 511 GLUnurbsObj *gl_nurb; >> 512 gl_nurb = gluNewNurbsRenderer (); >> 513 >> 514 GLfloat *u_knot_array, *u_knot_array_ptr; >> 515 u_knot_array = u_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::U)]; >> 516 G4NURBS::KnotsIterator u_iterator (nurb, G4NURBS::U); >> 517 while (u_iterator.pick (u_knot_array_ptr++)); >> 518 >> 519 GLfloat *v_knot_array, *v_knot_array_ptr; >> 520 v_knot_array = v_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::V)]; >> 521 G4NURBS::KnotsIterator v_iterator (nurb, G4NURBS::V); >> 522 while (v_iterator.pick (v_knot_array_ptr++)); >> 523 >> 524 GLfloat *ctrl_pnt_array, *ctrl_pnt_array_ptr; >> 525 ctrl_pnt_array = ctrl_pnt_array_ptr = >> 526 new GLfloat [nurb.GettotalnbrCtrlPts () * G4NURBS::NofC]; >> 527 G4NURBS::CtrlPtsCoordsIterator c_p_iterator (nurb); >> 528 while (c_p_iterator.pick (ctrl_pnt_array_ptr++)); 844 529 845 void G4OpenGLSceneHandler::AddCompound(const G << 530 const G4Colour& c = GetColour (nurb); 846 G4VSceneHandler::AddCompound(digi); // For << 847 } << 848 531 849 void G4OpenGLSceneHandler::AddCompound(const G << 532 switch (GetDrawingStyle(nurb)) { 850 G4VSceneHandler::AddCompound(hits); // For << 533 >> 534 case (G4ViewParameters::hlhsr): >> 535 // G4cout << "Hidden line removal not implememented in G4OpenGL.\n" >> 536 // << "Using hidden surface removal." << G4endl; >> 537 case (G4ViewParameters::hsr): >> 538 { >> 539 glEnable (GL_LIGHTING); >> 540 glEnable (GL_DEPTH_TEST); >> 541 glEnable (GL_AUTO_NORMAL); >> 542 glEnable (GL_NORMALIZE); >> 543 gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_FILL); >> 544 gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0); >> 545 GLfloat materialColour [4]; >> 546 materialColour [0] = c.GetRed (); >> 547 materialColour [1] = c.GetGreen (); >> 548 materialColour [2] = c.GetBlue (); >> 549 materialColour [3] = 1.0; >> 550 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour); >> 551 break; >> 552 } >> 553 case (G4ViewParameters::hlr): >> 554 // G4cout << "Hidden line removal not implememented in G4OpenGL.\n" >> 555 // << "Using wireframe." << G4endl; >> 556 case (G4ViewParameters::wireframe): >> 557 default: >> 558 glDisable (GL_LIGHTING); >> 559 // glDisable (GL_DEPTH_TEST); >> 560 glEnable (GL_DEPTH_TEST); >> 561 glDisable (GL_AUTO_NORMAL); >> 562 glDisable (GL_NORMALIZE); >> 563 gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON); >> 564 gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0); >> 565 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ()); >> 566 break; >> 567 } >> 568 >> 569 gluBeginSurface (gl_nurb); >> 570 G4int u_stride = 4; >> 571 G4int v_stride = nurb.GetnbrCtrlPts(G4NURBS::U) * 4; >> 572 >> 573 gluNurbsSurface (gl_nurb, >> 574 nurb.GetnbrKnots (G4NURBS::U), (GLfloat*)u_knot_array, >> 575 nurb.GetnbrKnots (G4NURBS::V), (GLfloat*)v_knot_array, >> 576 u_stride, >> 577 v_stride, >> 578 ctrl_pnt_array, >> 579 nurb.GetUorder (), >> 580 nurb.GetVorder (), >> 581 GL_MAP2_VERTEX_4); >> 582 >> 583 gluEndSurface (gl_nurb); >> 584 >> 585 delete [] u_knot_array; // These should be allocated with smart allocators >> 586 delete [] v_knot_array; // to avoid memory explosion. >> 587 delete [] ctrl_pnt_array; >> 588 >> 589 gluDeleteNurbsRenderer (gl_nurb); 851 } 590 } 852 591 853 void G4OpenGLSceneHandler::AddCompound(const G << 592 void G4OpenGLSceneHandler::AddThis(const G4VTrajectory& traj) { 854 G4VSceneHandler::AddCompound(hits); // For << 593 G4VSceneHandler::AddThis(traj); // For now. 855 } 594 } 856 595 857 void G4OpenGLSceneHandler::AddCompound(const G << 596 void G4OpenGLSceneHandler::AddThis(const G4VHit& hit) { 858 StandardSpecialMeshRendering(mesh); << 597 G4VSceneHandler::AddThis(hit); // For now. 859 } 598 } >> 599 >> 600 #endif 860 601