00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifdef G4VIS_BUILD_OPENGL_DRIVER
00034
00035
00036 #include "G4NURBS.hh"
00037
00038
00039
00040 #define CENTERLINE_CLPP
00041
00042
00043 #include "G4OpenGLStoredSceneHandler.hh"
00044
00045 #include "G4PhysicalVolumeModel.hh"
00046 #include "G4LogicalVolumeModel.hh"
00047 #include "G4VPhysicalVolume.hh"
00048 #include "G4LogicalVolume.hh"
00049 #include "G4Polyline.hh"
00050 #include "G4Polymarker.hh"
00051 #include "G4Text.hh"
00052 #include "G4Circle.hh"
00053 #include "G4Square.hh"
00054 #include "G4Polyhedron.hh"
00055 #include "G4AttHolder.hh"
00056 #include "G4OpenGLTransform3D.hh"
00057 #include "G4OpenGLViewer.hh"
00058 #include "G4AttHolder.hh"
00059
00060 #include <typeinfo>
00061
00062 G4OpenGLStoredSceneHandler::PO::PO():
00063 fDisplayListId(0),
00064 fPickName(0),
00065 fpG4TextPlus(0),
00066 fMarkerOrPolyline(false)
00067 {}
00068
00069 G4OpenGLStoredSceneHandler::PO::PO(const G4OpenGLStoredSceneHandler::PO& po):
00070 fDisplayListId(po.fDisplayListId),
00071 fTransform(po.fTransform),
00072 fPickName(po.fPickName),
00073 fColour(po.fColour),
00074 fpG4TextPlus(po.fpG4TextPlus? new G4TextPlus(*po.fpG4TextPlus): 0),
00075 fMarkerOrPolyline(po.fMarkerOrPolyline)
00076 {}
00077
00078 G4OpenGLStoredSceneHandler::PO::PO(G4int id, const G4Transform3D& tr):
00079 fDisplayListId(id),
00080 fTransform(tr),
00081 fPickName(0),
00082 fpG4TextPlus(0),
00083 fMarkerOrPolyline(false)
00084 {}
00085
00086 G4OpenGLStoredSceneHandler::PO::~PO()
00087 {
00088 delete fpG4TextPlus;
00089 }
00090
00091 G4OpenGLStoredSceneHandler::PO& G4OpenGLStoredSceneHandler::PO::operator=
00092 (const G4OpenGLStoredSceneHandler::PO& rhs)
00093 {
00094 if (&rhs == this) return *this;
00095 fDisplayListId = rhs.fDisplayListId;
00096 fTransform = rhs.fTransform;
00097 fPickName = rhs.fPickName;
00098 fColour = rhs.fColour;
00099 fpG4TextPlus = rhs.fpG4TextPlus? new G4TextPlus(*rhs.fpG4TextPlus): 0;
00100 fMarkerOrPolyline = rhs.fMarkerOrPolyline;
00101 return *this;
00102 }
00103
00104 G4OpenGLStoredSceneHandler::TO::TO():
00105 fDisplayListId(0),
00106 fPickName(0),
00107 fStartTime(-DBL_MAX),
00108 fEndTime(DBL_MAX),
00109 fpG4TextPlus(0),
00110 fMarkerOrPolyline(false)
00111 {}
00112
00113 G4OpenGLStoredSceneHandler::TO::TO(const G4OpenGLStoredSceneHandler::TO& to):
00114 fDisplayListId(to.fDisplayListId),
00115 fTransform(to.fTransform),
00116 fPickName(to.fPickName),
00117 fStartTime(to.fStartTime),
00118 fEndTime(to.fEndTime),
00119 fColour(to.fColour),
00120 fpG4TextPlus(to.fpG4TextPlus? new G4TextPlus(*to.fpG4TextPlus): 0),
00121 fMarkerOrPolyline(to.fMarkerOrPolyline)
00122 {}
00123
00124 G4OpenGLStoredSceneHandler::TO::TO(G4int id, const G4Transform3D& tr):
00125 fDisplayListId(id),
00126 fTransform(tr),
00127 fPickName(0),
00128 fStartTime(-DBL_MAX),
00129 fEndTime(DBL_MAX),
00130 fpG4TextPlus(0),
00131 fMarkerOrPolyline(false)
00132 {}
00133
00134 G4OpenGLStoredSceneHandler::TO::~TO()
00135 {
00136 delete fpG4TextPlus;
00137 }
00138
00139 G4OpenGLStoredSceneHandler::TO& G4OpenGLStoredSceneHandler::TO::operator=
00140 (const G4OpenGLStoredSceneHandler::TO& rhs)
00141 {
00142 if (&rhs == this) return *this;
00143 fDisplayListId = rhs.fDisplayListId;
00144 fTransform = rhs.fTransform;
00145 fPickName = rhs.fPickName;
00146 fStartTime = rhs.fStartTime;
00147 fEndTime = rhs.fEndTime;
00148 fColour = rhs.fColour;
00149 fpG4TextPlus = rhs.fpG4TextPlus? new G4TextPlus(*rhs.fpG4TextPlus): 0;
00150 fMarkerOrPolyline = rhs.fMarkerOrPolyline;
00151 return *this;
00152 }
00153
00154 G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler
00155 (G4VGraphicsSystem& system,
00156 const G4String& name):
00157 G4OpenGLSceneHandler (system, fSceneIdCount++, name),
00158 fTopPODL (0)
00159 {}
00160
00161 G4OpenGLStoredSceneHandler::~G4OpenGLStoredSceneHandler ()
00162 {}
00163
00164 void G4OpenGLStoredSceneHandler::BeginPrimitives
00165 (const G4Transform3D& objectTransformation)
00166 {
00167 G4OpenGLSceneHandler::BeginPrimitives (objectTransformation);
00168 if (fReadyForTransients) glDrawBuffer (GL_FRONT);
00169
00170 }
00171
00172 void G4OpenGLStoredSceneHandler::EndPrimitives ()
00173 {
00174
00175 ScaledFlush();
00176 glDrawBuffer (GL_BACK);
00177 G4OpenGLSceneHandler::EndPrimitives ();
00178 }
00179
00180 void G4OpenGLStoredSceneHandler::BeginPrimitives2D
00181 (const G4Transform3D& objectTransformation)
00182 {
00183 G4OpenGLSceneHandler::BeginPrimitives2D(objectTransformation);
00184 if (fReadyForTransients) glDrawBuffer (GL_FRONT);
00185 }
00186
00187 void G4OpenGLStoredSceneHandler::EndPrimitives2D ()
00188 {
00189
00190 ScaledFlush();
00191 glDrawBuffer (GL_BACK);
00192 G4OpenGLSceneHandler::EndPrimitives2D ();
00193 }
00194
00195 G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Visible& visible)
00196 {
00197 const G4Colour& c = GetColour (visible);
00198 G4double opacity = c.GetAlpha ();
00199
00200 G4bool transparency_enabled = true;
00201 G4bool isMarkerNotHidden = true;
00202 G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
00203 if (pViewer) {
00204 transparency_enabled = pViewer->transparency_enabled;
00205 isMarkerNotHidden = pViewer->fVP.IsMarkerNotHidden();
00206 }
00207
00208 G4bool isMarker = false;
00209 try {
00210 (void) dynamic_cast<const G4VMarker&>(visible);
00211 isMarker = true;
00212 }
00213 catch (std::bad_cast) {}
00214
00215 G4bool isPolyline = false;
00216 try {
00217 (void) dynamic_cast<const G4Polyline&>(visible);
00218 isPolyline = true;
00219 }
00220 catch (std::bad_cast) {}
00221
00222 G4bool isTransparent = opacity < 1.;
00223 G4bool isMarkerOrPolyline = isMarker || isPolyline;
00224 G4bool treatAsTransparent = transparency_enabled && isTransparent;
00225 G4bool treatAsNotHidden = isMarkerNotHidden && isMarkerOrPolyline;
00226
00227 if (fProcessing2D) glDisable (GL_DEPTH_TEST);
00228 else {
00229 if (isMarkerOrPolyline && isMarkerNotHidden)
00230 glDisable (GL_DEPTH_TEST);
00231 else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL);}
00232 }
00233
00234 if (fThreePassCapable) {
00235
00236
00237
00238
00239 if (!(fSecondPassForTransparency || fThirdPassForNonHiddenMarkers)) {
00240
00241 if (treatAsTransparent) {
00242 fSecondPassForTransparencyRequested = true;
00243 }
00244 if (treatAsNotHidden) {
00245 fThirdPassForNonHiddenMarkersRequested = true;
00246 }
00247
00248 if (treatAsTransparent || treatAsNotHidden) {
00249 return false;
00250 }
00251 }
00252
00253
00254 if (fSecondPassForTransparency) {
00255 if (!treatAsTransparent) {
00256 return false;
00257 }
00258 }
00259
00260
00261 if (fThirdPassForNonHiddenMarkers) {
00262 if (!treatAsNotHidden) {
00263 return false;
00264
00265 }
00266 }
00267 }
00268
00269
00270 G4bool isPicking = false;
00271 if (fpViewer->GetViewParameters().IsPicking()) {
00272 isPicking = true;
00273 glLoadName(++fPickName);
00274 G4AttHolder* holder = new G4AttHolder;
00275 LoadAtts(visible, holder);
00276 fPickMap[fPickName] = holder;
00277 }
00278
00279
00280 const G4VSolid* pSolid = 0;
00281 G4PhysicalVolumeModel* pPVModel =
00282 dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
00283 if (fpViewer->GetViewParameters().GetVisAttributesModifiers().size())
00284
00285 goto end_of_display_list_reuse_test;
00286 if (pPVModel) {
00287
00288
00289 G4LogicalVolumeModel* pLVModel =
00290 dynamic_cast<G4LogicalVolumeModel*>(pPVModel);
00291 if (pLVModel)
00292
00293 goto end_of_display_list_reuse_test;
00294
00295
00296
00297
00298
00299 pSolid = pPVModel->GetCurrentPV()->GetLogicalVolume()->GetSolid();
00300 EAxis axis = kRho;
00301 G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
00302 if (pCurrentPV -> IsReplicated ()) {
00303 G4int nReplicas;
00304 G4double width;
00305 G4double offset;
00306 G4bool consuming;
00307 pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
00308 }
00309
00310
00311 if (!(pCurrentPV -> IsParameterised ()) &&
00312
00313
00314 !(pCurrentPV -> IsReplicated () && axis == kRho) &&
00315
00316 (fSolidMap.find (pSolid) != fSolidMap.end ())) {
00317 fDisplayListId = fSolidMap [pSolid];
00318 PO po(fDisplayListId,fObjectTransformation);
00319 if (isPicking) po.fPickName = fPickName;
00320 po.fColour = c;
00321 po.fMarkerOrPolyline = isMarkerOrPolyline;
00322 fPOList.push_back(po);
00323
00324
00325
00326
00327 (void) ExtraPOProcessing(G4Visible(), fPOList.size() - 1);
00328 return false;
00329 }
00330 }
00331 end_of_display_list_reuse_test:
00332
00333
00334
00335
00336
00337 if (fMemoryForDisplayLists) {
00338 fDisplayListId = glGenLists (1);
00339 if (glGetError() == GL_OUT_OF_MEMORY ||
00340 fDisplayListId > fDisplayListLimit) {
00341 G4cout <<
00342 "********************* WARNING! ********************"
00343 "\n* Display list limit reached in OpenGL."
00344 "\n* Continuing drawing WITHOUT STORING. Scene only partially refreshable."
00345 "\n* Current limit: " << fDisplayListLimit <<
00346 ". Change with \"/vis/ogl/set/displayListLimit\"."
00347 "\n***************************************************"
00348 << G4endl;
00349 fMemoryForDisplayLists = false;
00350 }
00351 }
00352
00353 if (pSolid) fSolidMap [pSolid] = fDisplayListId;
00354
00355 if (fMemoryForDisplayLists) {
00356 if (fReadyForTransients) {
00357 TO to(fDisplayListId, fObjectTransformation);
00358 if (isPicking) to.fPickName = fPickName;
00359 to.fColour = c;
00360 const G4VisAttributes* pVA =
00361 fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
00362 to.fStartTime = pVA->GetStartTime();
00363 to.fEndTime = pVA->GetEndTime();
00364 to.fMarkerOrPolyline = isMarkerOrPolyline;
00365 fTOList.push_back(to);
00366
00367
00368
00369
00370
00371 glPushMatrix();
00372 G4OpenGLTransform3D oglt (fObjectTransformation);
00373 glMultMatrixd (oglt.GetGLMatrix ());
00374 if (transparency_enabled) {
00375 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
00376 } else {
00377 glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
00378 }
00379 (void) ExtraTOProcessing(visible, fTOList.size() - 1);
00380
00381
00382
00383 glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
00384 } else {
00385 PO po(fDisplayListId, fObjectTransformation);
00386 if (isPicking) po.fPickName = fPickName;
00387 po.fColour = c;
00388 po.fMarkerOrPolyline = isMarkerOrPolyline;
00389 fPOList.push_back(po);
00390
00391
00392
00393
00394
00395 if (transparency_enabled) {
00396 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
00397 } else {
00398 glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
00399 }
00400 G4bool usesGLCommands = ExtraPOProcessing(visible, fPOList.size() - 1);
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 if (!usesGLCommands) return false;
00411 glNewList (fDisplayListId, GL_COMPILE);
00412 }
00413 } else {
00414 glDrawBuffer (GL_FRONT);
00415 glPushMatrix();
00416 G4OpenGLTransform3D oglt (fObjectTransformation);
00417 glMultMatrixd (oglt.GetGLMatrix ());
00418 if (transparency_enabled) {
00419 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha());
00420 } else {
00421 glColor3d(c.GetRed(),c.GetGreen(),c.GetBlue());
00422 }
00423 }
00424
00425 if (fProcessing2D) {
00426
00427
00428 glMatrixMode (GL_PROJECTION);
00429 glPushMatrix();
00430 glLoadIdentity();
00431 glOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
00432 glMatrixMode (GL_MODELVIEW);
00433 glPushMatrix();
00434 glLoadIdentity();
00435 G4OpenGLTransform3D oglt (fObjectTransformation);
00436 glMultMatrixd (oglt.GetGLMatrix ());
00437 glDisable(GL_DEPTH_TEST);
00438 glDisable (GL_LIGHTING);
00439 }
00440
00441 return true;
00442 }
00443
00444 void G4OpenGLStoredSceneHandler::AddPrimitivePostamble()
00445 {
00446 if (fProcessing2D) {
00447
00448 glMatrixMode (GL_PROJECTION);
00449 glPopMatrix();
00450 glMatrixMode (GL_MODELVIEW);
00451 glPopMatrix();
00452 }
00453
00454
00455 if (glGetError() == GL_OUT_OF_MEMORY) {
00456 G4cout <<
00457 "ERROR: G4OpenGLStoredSceneHandler::AddPrimitivePostamble: Failure"
00458 " to allocate display List for fTopPODL - try OpenGL Immediated mode."
00459 << G4endl;
00460 }
00461 if (fMemoryForDisplayLists) {
00462 glEndList();
00463 if (glGetError() == GL_OUT_OF_MEMORY) {
00464 G4cout <<
00465 "ERROR: G4OpenGLStoredSceneHandler::AddPrimitivePostamble: Failure"
00466 " to allocate display List for fTopPODL - try OpenGL Immediated mode."
00467 << G4endl;
00468 }
00469 }
00470 if (fReadyForTransients || !fMemoryForDisplayLists) {
00471 glPopMatrix();
00472 }
00473 }
00474
00475 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline)
00476 {
00477 G4bool furtherprocessing = AddPrimitivePreamble(polyline);
00478 if (furtherprocessing) {
00479 G4OpenGLSceneHandler::AddPrimitive(polyline);
00480 AddPrimitivePostamble();
00481 }
00482 }
00483
00484 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
00485 {
00486 G4bool furtherprocessing = AddPrimitivePreamble(polymarker);
00487 if (furtherprocessing) {
00488 G4OpenGLSceneHandler::AddPrimitive(polymarker);
00489 AddPrimitivePostamble();
00490 }
00491 }
00492
00493 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Text& text)
00494 {
00495
00496
00497
00498 G4bool furtherprocessing = AddPrimitivePreamble(text);
00499 if (furtherprocessing) {
00500 G4OpenGLSceneHandler::AddPrimitive(text);
00501 AddPrimitivePostamble();
00502 }
00503 }
00504
00505 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle)
00506 {
00507 G4bool furtherprocessing = AddPrimitivePreamble(circle);
00508 if (furtherprocessing) {
00509 G4OpenGLSceneHandler::AddPrimitive(circle);
00510 AddPrimitivePostamble();
00511 }
00512 }
00513
00514 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square)
00515 {
00516 G4bool furtherprocessing = AddPrimitivePreamble(square);
00517 if (furtherprocessing) {
00518 G4OpenGLSceneHandler::AddPrimitive(square);
00519 AddPrimitivePostamble();
00520 }
00521 }
00522
00523 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Scale& scale)
00524 {
00525
00526 G4OpenGLSceneHandler::AddPrimitive(scale);
00527 }
00528
00529 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron)
00530 {
00531
00532
00533
00534 G4bool furtherprocessing = AddPrimitivePreamble(polyhedron);
00535 if (furtherprocessing) {
00536 G4OpenGLSceneHandler::AddPrimitive(polyhedron);
00537 AddPrimitivePostamble();
00538 }
00539 }
00540
00541 void G4OpenGLStoredSceneHandler::AddPrimitive (const G4NURBS& nurbs)
00542 {
00543
00544
00545
00546 G4bool furtherprocessing = AddPrimitivePreamble(nurbs);
00547 if (furtherprocessing) {
00548 G4OpenGLSceneHandler::AddPrimitive(nurbs);
00549 AddPrimitivePostamble();
00550 }
00551 }
00552
00553 void G4OpenGLStoredSceneHandler::BeginModeling () {
00554 G4VSceneHandler::BeginModeling();
00555
00556
00557
00558
00559 }
00560
00561 void G4OpenGLStoredSceneHandler::EndModeling () {
00562
00563 fTopPODL = glGenLists (1);
00564 if (glGetError() == GL_OUT_OF_MEMORY) {
00565 G4cout <<
00566 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
00567 " display List for fTopPODL - try OpenGL Immediated mode."
00568 << G4endl;
00569 } else {
00570
00571 glNewList (fTopPODL, GL_COMPILE); {
00572 for (size_t i = 0; i < fPOList.size (); i++) {
00573 glPushMatrix();
00574 G4OpenGLTransform3D oglt (fPOList[i].fTransform);
00575 glMultMatrixd (oglt.GetGLMatrix ());
00576 if (fpViewer->GetViewParameters().IsPicking())
00577 glLoadName(fPOList[i].fPickName);
00578 glCallList (fPOList[i].fDisplayListId);
00579 glPopMatrix();
00580 }
00581 }
00582 glEndList ();
00583
00584 if (glGetError() == GL_OUT_OF_MEMORY) {
00585 G4cout <<
00586 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
00587 " display List for fTopPODL - try OpenGL Immediated mode."
00588 << G4endl;
00589 }
00590 }
00591
00592 G4VSceneHandler::EndModeling ();
00593 }
00594
00595 void G4OpenGLStoredSceneHandler::ClearStore () {
00596
00597
00598
00599 G4VSceneHandler::ClearStore ();
00600
00601
00602 for (size_t i = 0; i < fPOList.size (); i++)
00603 glDeleteLists (fPOList[i].fDisplayListId, 1);
00604 if (fTopPODL) glDeleteLists (fTopPODL, 1);
00605 fTopPODL = 0;
00606
00607
00608 fPOList.clear ();
00609 fSolidMap.clear ();
00610 ClearAndDestroyAtts();
00611
00612
00613 for (size_t i = 0; i < fTOList.size (); i++)
00614 glDeleteLists(fTOList[i].fDisplayListId, 1);
00615 fTOList.clear ();
00616
00617 fMemoryForDisplayLists = true;
00618 }
00619
00620 void G4OpenGLStoredSceneHandler::ClearTransientStore ()
00621 {
00622
00623
00624
00625 for (size_t i = 0; i < fTOList.size (); i++)
00626 glDeleteLists(fTOList[i].fDisplayListId, 1);
00627 fTOList.clear ();
00628
00629 fMemoryForDisplayLists = true;
00630
00631
00632 if (fpViewer) {
00633 fpViewer -> SetView ();
00634 fpViewer -> ClearView ();
00635 fpViewer -> DrawView ();
00636 }
00637 }
00638
00639 G4int G4OpenGLStoredSceneHandler::fSceneIdCount = 0;
00640
00641 G4int G4OpenGLStoredSceneHandler::fDisplayListId = 0;
00642 G4bool G4OpenGLStoredSceneHandler::fMemoryForDisplayLists = true;
00643 G4int G4OpenGLStoredSceneHandler::fDisplayListLimit = 50000;
00644
00645 #endif