00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TGLViewer.h"
00013 #include "TGLIncludes.h"
00014 #include "TGLStopwatch.h"
00015 #include "TGLRnrCtx.h"
00016 #include "TGLSelectBuffer.h"
00017 #include "TGLLightSet.h"
00018 #include "TGLManipSet.h"
00019 #include "TGLCameraOverlay.h"
00020 #include "TGLAutoRotator.h"
00021
00022 #include "TGLScenePad.h"
00023 #include "TGLLogicalShape.h"
00024 #include "TGLPhysicalShape.h"
00025 #include "TGLObject.h"
00026 #include "TGLStopwatch.h"
00027 #include "TBuffer3D.h"
00028 #include "TBuffer3DTypes.h"
00029
00030 #include "TGLOutput.h"
00031
00032 #include "TVirtualPad.h"
00033 #include "TVirtualX.h"
00034
00035 #include "TMath.h"
00036 #include "TColor.h"
00037 #include "TError.h"
00038 #include "TClass.h"
00039 #include "TROOT.h"
00040
00041
00042 #include "Buttons.h"
00043 #include "GuiTypes.h"
00044
00045 #include "TVirtualGL.h"
00046
00047 #include "TGLWidget.h"
00048 #include "TGLFBO.h"
00049 #include "TGLViewerEditor.h"
00050 #include "TGedEditor.h"
00051 #include "TGLPShapeObj.h"
00052
00053 #include "KeySymbols.h"
00054 #include "TContextMenu.h"
00055 #include "TImage.h"
00056
00057 #include <stdexcept>
00058
00059 #ifndef GL_BGRA
00060 #define GL_BGRA GL_BGRA_EXT
00061 #endif
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 ClassImp(TGLViewer);
00094
00095 TGLColorSet TGLViewer::fgDefaultColorSet;
00096 Bool_t TGLViewer::fgUseDefaultColorSetForNewViewers = kFALSE;
00097
00098
00099 TGLViewer::TGLViewer(TVirtualPad * pad, Int_t x, Int_t y,
00100 Int_t width, Int_t height) :
00101 fPad(pad),
00102 fContextMenu(0),
00103 fPerspectiveCameraXOZ(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)),
00104 fPerspectiveCameraYOZ(TGLVector3( 0.0,-1.0, 0.0), TGLVector3(1.0, 0.0, 0.0)),
00105 fPerspectiveCameraXOY(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 0.0, 1.0)),
00106 fOrthoXOYCamera (TGLOrthoCamera::kXOY, TGLVector3( 0.0, 0.0, 1.0), TGLVector3(0.0, 1.0, 0.0)),
00107 fOrthoXOZCamera (TGLOrthoCamera::kXOZ, TGLVector3( 0.0,-1.0, 0.0), TGLVector3(0.0, 0.0, 1.0)),
00108 fOrthoZOYCamera (TGLOrthoCamera::kZOY, TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)),
00109 fOrthoXnOYCamera(TGLOrthoCamera::kXnOY, TGLVector3( 0.0, 0.0,-1.0), TGLVector3(0.0, 1.0, 0.0)),
00110 fOrthoXnOZCamera(TGLOrthoCamera::kXnOZ, TGLVector3( 0.0, 1.0, 0.0), TGLVector3(0.0, 0.0, 1.0)),
00111 fOrthoZnOYCamera(TGLOrthoCamera::kZnOY, TGLVector3( 1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)),
00112 fCurrentCamera(&fPerspectiveCameraXOZ),
00113 fAutoRotator(0),
00114
00115 fStereo (kFALSE),
00116 fStereoZeroParallax (0.03f),
00117 fStereoEyeOffsetFac (1.0f),
00118 fStereoFrustumAsymFac (1.0f),
00119
00120 fLightSet (0),
00121 fClipSet (0),
00122 fSelectedPShapeRef (0),
00123 fCurrentOvlElm (0),
00124
00125 fEventHandler(0),
00126 fGedEditor(0),
00127 fPShapeWrap(0),
00128 fPushAction(kPushStd), fDragAction(kDragNone),
00129 fRedrawTimer(0),
00130 fMaxSceneDrawTimeHQ(5000),
00131 fMaxSceneDrawTimeLQ(100),
00132 fPointScale (1), fLineScale(1), fSmoothPoints(kFALSE), fSmoothLines(kFALSE),
00133 fAxesType(TGLUtil::kAxesNone),
00134 fAxesDepthTest(kTRUE),
00135 fReferenceOn(kFALSE),
00136 fReferencePos(0.0, 0.0, 0.0),
00137 fDrawCameraCenter(kFALSE),
00138 fCameraOverlay(0),
00139 fSmartRefresh(kFALSE),
00140 fDebugMode(kFALSE),
00141 fIsPrinting(kFALSE),
00142 fPictureFileName("viewer.jpg"),
00143 fFader(0),
00144 fGLWidget(0),
00145 fGLDevice(-1),
00146 fGLCtxId(0),
00147 fIgnoreSizesOnUpdate(kFALSE),
00148 fResetCamerasOnUpdate(kTRUE),
00149 fResetCamerasOnNextUpdate(kFALSE)
00150 {
00151
00152
00153
00154
00155
00156 InitSecondaryObjects();
00157
00158 SetViewport(x, y, width, height);
00159 }
00160
00161
00162 TGLViewer::TGLViewer(TVirtualPad * pad) :
00163 fPad(pad),
00164 fContextMenu(0),
00165 fPerspectiveCameraXOZ(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)),
00166 fPerspectiveCameraYOZ(TGLVector3( 0.0,-1.0, 0.0), TGLVector3(1.0, 0.0, 0.0)),
00167 fPerspectiveCameraXOY(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 0.0, 1.0)),
00168 fOrthoXOYCamera (TGLOrthoCamera::kXOY, TGLVector3( 0.0, 0.0, 1.0), TGLVector3(0.0, 1.0, 0.0)),
00169 fOrthoXOZCamera (TGLOrthoCamera::kXOZ, TGLVector3( 0.0,-1.0, 0.0), TGLVector3(0.0, 0.0, 1.0)),
00170 fOrthoZOYCamera (TGLOrthoCamera::kZOY, TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)),
00171 fOrthoXnOYCamera(TGLOrthoCamera::kXnOY, TGLVector3( 0.0, 0.0,-1.0), TGLVector3(0.0, 1.0, 0.0)),
00172 fOrthoXnOZCamera(TGLOrthoCamera::kXnOZ, TGLVector3( 0.0, 1.0, 0.0), TGLVector3(0.0, 0.0, 1.0)),
00173 fOrthoZnOYCamera(TGLOrthoCamera::kZnOY, TGLVector3( 1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)),
00174 fCurrentCamera(&fPerspectiveCameraXOZ),
00175 fAutoRotator(0),
00176
00177 fStereo (kFALSE),
00178 fStereoZeroParallax (0.03f),
00179 fStereoEyeOffsetFac (1.0f),
00180 fStereoFrustumAsymFac (1.0f),
00181
00182 fLightSet (0),
00183 fClipSet (0),
00184 fSelectedPShapeRef (0),
00185 fCurrentOvlElm (0),
00186
00187 fEventHandler(0),
00188 fGedEditor(0),
00189 fPShapeWrap(0),
00190 fPushAction(kPushStd), fDragAction(kDragNone),
00191 fRedrawTimer(0),
00192 fMaxSceneDrawTimeHQ(5000),
00193 fMaxSceneDrawTimeLQ(100),
00194 fPointScale (1), fLineScale(1), fSmoothPoints(kFALSE), fSmoothLines(kFALSE),
00195 fAxesType(TGLUtil::kAxesNone),
00196 fAxesDepthTest(kTRUE),
00197 fReferenceOn(kFALSE),
00198 fReferencePos(0.0, 0.0, 0.0),
00199 fDrawCameraCenter(kFALSE),
00200 fCameraOverlay(0),
00201 fSmartRefresh(kFALSE),
00202 fDebugMode(kFALSE),
00203 fIsPrinting(kFALSE),
00204 fPictureFileName("viewer.jpg"),
00205 fFader(0),
00206 fGLWidget(0),
00207 fGLDevice(fPad->GetGLDevice()),
00208 fGLCtxId(0),
00209 fIgnoreSizesOnUpdate(kFALSE),
00210 fResetCamerasOnUpdate(kTRUE),
00211 fResetCamerasOnNextUpdate(kFALSE)
00212 {
00213
00214
00215
00216
00217
00218
00219 InitSecondaryObjects();
00220
00221 if (fGLDevice != -1) {
00222
00223 fGLCtxId = new TGLContextIdentity;
00224 fGLCtxId->AddRef(0);
00225 Int_t viewport[4] = {0};
00226 gGLManager->ExtractViewport(fGLDevice, viewport);
00227 SetViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
00228 }
00229 }
00230
00231
00232 void TGLViewer::InitSecondaryObjects()
00233 {
00234
00235
00236 fLightSet = new TGLLightSet;
00237 fClipSet = new TGLClipSet;
00238 AddOverlayElement(fClipSet);
00239
00240 fSelectedPShapeRef = new TGLManipSet;
00241 fSelectedPShapeRef->SetDrawBBox(kTRUE);
00242 AddOverlayElement(fSelectedPShapeRef);
00243
00244 fPShapeWrap = new TGLPShapeObj(0, this);
00245
00246 fLightColorSet.StdLightBackground();
00247 if (fgUseDefaultColorSetForNewViewers) {
00248 fRnrCtx->ChangeBaseColorSet(&fgDefaultColorSet);
00249 } else {
00250 if (fPad) {
00251 fRnrCtx->ChangeBaseColorSet(&fLightColorSet);
00252 fLightColorSet.Background().SetColor(fPad->GetFillColor());
00253 fLightColorSet.Foreground().SetColor(fPad->GetLineColor());
00254 } else {
00255 fRnrCtx->ChangeBaseColorSet(&fDarkColorSet);
00256 }
00257 }
00258
00259 fCameraOverlay = new TGLCameraOverlay(kFALSE, kFALSE);
00260 AddOverlayElement(fCameraOverlay);
00261
00262 fRedrawTimer = new TGLRedrawTimer(*this);
00263 }
00264
00265
00266 TGLViewer::~TGLViewer()
00267 {
00268
00269
00270 delete fAutoRotator;
00271
00272 delete fLightSet;
00273
00274
00275 delete fContextMenu;
00276 delete fRedrawTimer;
00277
00278 if (fEventHandler) {
00279 if (fGLWidget)
00280 fGLWidget->SetEventHandler(0);
00281 delete fEventHandler;
00282 }
00283
00284 if (fPad)
00285 fPad->ReleaseViewer3D();
00286 if (fGLDevice != -1)
00287 fGLCtxId->Release(0);
00288 }
00289
00290
00291
00292 void TGLViewer::PadPaint(TVirtualPad* pad)
00293 {
00294
00295
00296
00297
00298
00299
00300 TGLScenePad* scenepad = 0;
00301 for (SceneInfoList_i si = fScenes.begin(); si != fScenes.end(); ++si)
00302 {
00303 scenepad = dynamic_cast<TGLScenePad*>((*si)->GetScene());
00304 if (scenepad && scenepad->GetPad() == pad)
00305 break;
00306 scenepad = 0;
00307 }
00308 if (scenepad == 0)
00309 {
00310 scenepad = new TGLScenePad(pad);
00311 AddScene(scenepad);
00312 }
00313
00314 scenepad->PadPaintFromViewer(this);
00315
00316 PostSceneBuildSetup(fResetCamerasOnNextUpdate || fResetCamerasOnUpdate);
00317 fResetCamerasOnNextUpdate = kFALSE;
00318
00319 RequestDraw();
00320 }
00321
00322
00323
00324
00325
00326
00327 void TGLViewer::UpdateScene(Bool_t redraw)
00328 {
00329
00330
00331
00332
00333 fRedrawTimer->Stop();
00334
00335 for (SceneInfoList_i si = fScenes.begin(); si != fScenes.end(); ++si)
00336 {
00337 TGLScenePad* scenepad = dynamic_cast<TGLScenePad*>((*si)->GetScene());
00338 if (scenepad)
00339 scenepad->PadPaintFromViewer(this);
00340 }
00341
00342 PostSceneBuildSetup(fResetCamerasOnNextUpdate || fResetCamerasOnUpdate);
00343 fResetCamerasOnNextUpdate = kFALSE;
00344
00345 if (redraw)
00346 RequestDraw();
00347 }
00348
00349
00350 void TGLViewer::ResetCurrentCamera()
00351 {
00352
00353
00354 MergeSceneBBoxes(fOverallBoundingBox);
00355 CurrentCamera().Setup(fOverallBoundingBox, kTRUE);
00356 }
00357
00358
00359 void TGLViewer::SetupCameras(Bool_t reset)
00360 {
00361
00362
00363 if (IsLocked()) {
00364 Error("TGLViewer::SetupCameras", "expected kUnlocked, found %s", LockName(CurrentLock()));
00365 return;
00366 }
00367
00368
00369 const TGLBoundingBox & box = fOverallBoundingBox;
00370 if (!box.IsEmpty()) {
00371 fPerspectiveCameraYOZ.Setup(box, reset);
00372 fPerspectiveCameraXOZ.Setup(box, reset);
00373 fPerspectiveCameraXOY.Setup(box, reset);
00374 fOrthoXOYCamera.Setup(box, reset);
00375 fOrthoXOZCamera.Setup(box, reset);
00376 fOrthoZOYCamera.Setup(box, reset);
00377 fOrthoXnOYCamera.Setup(box, reset);
00378 fOrthoXnOZCamera.Setup(box, reset);
00379 fOrthoZnOYCamera.Setup(box, reset);
00380 }
00381 }
00382
00383
00384 void TGLViewer::PostSceneBuildSetup(Bool_t resetCameras)
00385 {
00386
00387
00388 MergeSceneBBoxes(fOverallBoundingBox);
00389 SetupCameras(resetCameras);
00390
00391
00392 fReferencePos.Set(fOverallBoundingBox.Center());
00393 RefreshPadEditor(this);
00394 }
00395
00396
00397
00398
00399
00400
00401 void TGLViewer::InitGL()
00402 {
00403
00404
00405 glEnable(GL_LIGHTING);
00406 glEnable(GL_DEPTH_TEST);
00407 glEnable(GL_CULL_FACE);
00408 glCullFace(GL_BACK);
00409 glClearColor(0.f, 0.f, 0.f, 0.f);
00410 glClearDepth(1.0);
00411 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
00412 glEnable(GL_COLOR_MATERIAL);
00413 glMaterialf(GL_BACK, GL_SHININESS, 0.0);
00414 glPolygonMode(GL_FRONT, GL_FILL);
00415 glDisable(GL_BLEND);
00416
00417 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
00418 Float_t lmodelAmb[] = {0.5f, 0.5f, 1.f, 1.f};
00419 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodelAmb);
00420 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
00421
00422 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
00423 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00424
00425 TGLUtil::CheckError("TGLViewer::InitGL");
00426 }
00427
00428
00429 void TGLViewer::RequestDraw(Short_t LODInput)
00430 {
00431
00432
00433
00434 fRedrawTimer->Stop();
00435
00436 if ((!fGLWidget && fGLDevice == -1) || (fGLWidget && !fGLWidget->IsMapped()))
00437 {
00438 return;
00439 }
00440
00441
00442 if ( ! TakeLock(kDrawLock)) {
00443
00444
00445 if (gDebug>3) {
00446 Info("TGLViewer::RequestDraw", "viewer locked - requesting another draw.");
00447 }
00448 fRedrawTimer->RequestDraw(100, LODInput);
00449 return;
00450 }
00451 fLOD = LODInput;
00452
00453 if (!gVirtualX->IsCmdThread())
00454 gROOT->ProcessLineFast(Form("((TGLViewer *)0x%lx)->DoDraw()", (ULong_t)this));
00455 else
00456 DoDraw();
00457 }
00458
00459
00460 void TGLViewer::SetupClipObject()
00461 {
00462
00463
00464 if (GetClipAutoUpdate())
00465 {
00466 fClipSet->SetupCurrentClip(fOverallBoundingBox);
00467 }
00468 else
00469 {
00470 fClipSet->SetupCurrentClipIfInvalid(fOverallBoundingBox);
00471 }
00472 }
00473
00474 void TGLViewer::PreRender()
00475 {
00476
00477
00478
00479 fCamera = fCurrentCamera;
00480 fClip = fClipSet->GetCurrentClip();
00481 if (fGLDevice != -1)
00482 {
00483 fRnrCtx->SetGLCtxIdentity(fGLCtxId);
00484 fGLCtxId->DeleteGLResources();
00485 }
00486
00487 TGLUtil::SetPointSizeScale(fPointScale * fRnrCtx->GetRenderScale());
00488 TGLUtil::SetLineWidthScale(fLineScale * fRnrCtx->GetRenderScale());
00489
00490 if (fSmoothPoints) glEnable(GL_POINT_SMOOTH); else glDisable(GL_POINT_SMOOTH);
00491 if (fSmoothLines) glEnable(GL_LINE_SMOOTH); else glDisable(GL_LINE_SMOOTH);
00492 if (fSmoothPoints || fSmoothLines)
00493 {
00494 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00495 glEnable(GL_BLEND);
00496 }
00497 else
00498 {
00499 glDisable(GL_BLEND);
00500 }
00501
00502 TGLViewerBase::PreRender();
00503
00504
00505 fLightSet->StdSetupLights(fOverallBoundingBox, *fCamera, fDebugMode);
00506 }
00507
00508
00509 void TGLViewer::PostRender()
00510 {
00511
00512
00513
00514 TGLViewerBase::PostRender();
00515
00516 TGLUtil::SetPointSizeScale(1);
00517 TGLUtil::SetLineWidthScale(1);
00518 }
00519
00520
00521 void TGLViewer::DoDraw(Bool_t swap_buffers)
00522 {
00523
00524
00525
00526
00527
00528
00529
00530 fRedrawTimer->Stop();
00531
00532 if (CurrentLock() != kDrawLock) {
00533 if ( ! TakeLock(kDrawLock)) {
00534 Error("TGLViewer::DoDraw", "viewer is %s", LockName(CurrentLock()));
00535 return;
00536 }
00537 }
00538
00539 TUnlocker ulck(this);
00540
00541 if (fGLDevice == -1 && (fViewport.Width() <= 1 || fViewport.Height() <= 1)) {
00542 if (gDebug > 2) {
00543 Info("TGLViewer::DoDraw()", "zero surface area, draw skipped.");
00544 }
00545 return;
00546 }
00547
00548 if (fGLDevice != -1) {
00549 Int_t viewport[4] = {};
00550 gGLManager->ExtractViewport(fGLDevice, viewport);
00551 SetViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
00552 }
00553
00554 TGLStopwatch timer;
00555 if (gDebug>2) {
00556 timer.Start();
00557 }
00558
00559
00560 fRnrCtx->SetRenderTimeOut(fLOD == TGLRnrCtx::kLODHigh ?
00561 fMaxSceneDrawTimeHQ :
00562 fMaxSceneDrawTimeLQ);
00563
00564 if (fStereo && fCurrentCamera->IsPerspective() && !fRnrCtx->GetGrabImage() &&
00565 !fIsPrinting)
00566 {
00567 DoDrawStereo(swap_buffers);
00568 }
00569 else
00570 {
00571 DoDrawMono(swap_buffers);
00572 }
00573
00574 ReleaseLock(kDrawLock);
00575
00576 if (gDebug>2) {
00577 Info("TGLViewer::DoDraw()", "Took %f msec", timer.End());
00578 }
00579
00580
00581
00582 if (CurrentCamera().UpdateInterest(kFALSE)) {
00583
00584 ResetSceneInfos();
00585 fRedrawTimer->RequestDraw(0, fLOD);
00586 }
00587
00588 if (fLOD != TGLRnrCtx::kLODHigh &&
00589 (fDragAction < kDragCameraRotate || fDragAction > kDragCameraDolly))
00590 {
00591
00592 fRedrawTimer->RequestDraw(100, TGLRnrCtx::kLODHigh);
00593 }
00594 }
00595
00596
00597 void TGLViewer::DoDrawMono(Bool_t swap_buffers)
00598 {
00599
00600
00601 MakeCurrent();
00602
00603 if (!fIsPrinting) PreDraw();
00604 PreRender();
00605
00606 fRnrCtx->StartStopwatch();
00607 if (fFader < 1)
00608 {
00609 RenderNonSelected();
00610 RenderSelected();
00611 DrawGuides();
00612 RenderOverlay(TGLOverlayElement::kAllVisible, kFALSE);
00613
00614 glClear(GL_DEPTH_BUFFER_BIT);
00615 fRnrCtx->SetHighlight(kTRUE);
00616 RenderSelected();
00617 fRnrCtx->SetHighlight(kFALSE);
00618 glClear(GL_DEPTH_BUFFER_BIT);
00619 DrawDebugInfo();
00620 }
00621 fRnrCtx->StopStopwatch();
00622
00623 PostRender();
00624
00625 if (fFader > 0)
00626 {
00627 FadeView(fFader);
00628 }
00629
00630 PostDraw();
00631
00632 if (swap_buffers)
00633 {
00634 SwapBuffers();
00635 }
00636 }
00637
00638
00639 void TGLViewer::DoDrawStereo(Bool_t swap_buffers)
00640 {
00641
00642
00643 TGLPerspectiveCamera &c = *dynamic_cast<TGLPerspectiveCamera*>(fCurrentCamera);
00644
00645 Float_t gl_near, gl_far, zero_p_dist;
00646 Float_t h_half, w_half;
00647 Float_t x_len_at_zero_parallax;
00648 Float_t stereo_offset;
00649 Float_t frustum_asym;
00650
00651 MakeCurrent();
00652
00653
00654 glDrawBuffer(GL_BACK_LEFT);
00655 PreDraw();
00656 PreRender();
00657
00658 gl_near = c.GetNearClip();
00659 gl_far = c.GetFarClip();
00660 zero_p_dist = gl_near + fStereoZeroParallax*(gl_far-gl_near);
00661
00662 h_half = TMath::Tan(0.5*TMath::DegToRad()*c.GetFOV()) * gl_near;
00663 w_half = h_half * fViewport.Aspect();
00664
00665 x_len_at_zero_parallax = 2.0f * w_half * zero_p_dist / gl_near;
00666 stereo_offset = 0.035f * x_len_at_zero_parallax * fStereoEyeOffsetFac;
00667
00668 frustum_asym = stereo_offset * gl_near / zero_p_dist * fStereoFrustumAsymFac;
00669
00670 TGLMatrix abs_trans(c.RefCamBase());
00671 abs_trans *= c.RefCamTrans();
00672 TGLVector3 left_vec = abs_trans.GetBaseVec(2);
00673
00674 glTranslatef(stereo_offset*left_vec[0], stereo_offset*left_vec[1], stereo_offset*left_vec[2]);
00675
00676 glMatrixMode(GL_PROJECTION);
00677 glLoadIdentity();
00678 glFrustum(-w_half + frustum_asym, w_half + frustum_asym,
00679 -h_half, h_half, gl_near, gl_far);
00680 glMatrixMode(GL_MODELVIEW);
00681
00682 fRnrCtx->StartStopwatch();
00683 if (fFader < 1)
00684 {
00685 RenderNonSelected();
00686 RenderSelected();
00687 DrawGuides();
00688 RenderOverlay(TGLOverlayElement::kAllVisible, kFALSE);
00689
00690 glClear(GL_DEPTH_BUFFER_BIT);
00691 fRnrCtx->SetHighlight(kTRUE);
00692 RenderSelected();
00693 fRnrCtx->SetHighlight(kFALSE);
00694 glClear(GL_DEPTH_BUFFER_BIT);
00695 DrawDebugInfo();
00696 }
00697 fRnrCtx->StopStopwatch();
00698
00699 PostRender();
00700
00701 if (fFader > 0)
00702 {
00703 FadeView(fFader);
00704 }
00705 PostDraw();
00706
00707
00708 glDrawBuffer(GL_BACK_RIGHT);
00709 PreDraw();
00710 PreRender();
00711
00712 glTranslatef(-stereo_offset*left_vec[0], -stereo_offset*left_vec[1], -stereo_offset*left_vec[2]);
00713
00714 glMatrixMode(GL_PROJECTION);
00715 glLoadIdentity();
00716 glFrustum(-w_half - frustum_asym, w_half - frustum_asym,
00717 -h_half, h_half, gl_near, gl_far);
00718 glMatrixMode(GL_MODELVIEW);
00719
00720 fRnrCtx->StartStopwatch();
00721 if (fFader < 1)
00722 {
00723 RenderNonSelected();
00724 RenderSelected();
00725 DrawGuides();
00726 RenderOverlay(TGLOverlayElement::kAllVisible, kFALSE);
00727
00728 glClear(GL_DEPTH_BUFFER_BIT);
00729 fRnrCtx->SetHighlight(kTRUE);
00730 RenderSelected();
00731 fRnrCtx->SetHighlight(kFALSE);
00732 glClear(GL_DEPTH_BUFFER_BIT);
00733 DrawDebugInfo();
00734 }
00735 fRnrCtx->StopStopwatch();
00736
00737 PostRender();
00738
00739 if (fFader > 0)
00740 {
00741 FadeView(fFader);
00742 }
00743 PostDraw();
00744
00745
00746 if (swap_buffers)
00747 {
00748 SwapBuffers();
00749 }
00750
00751 glDrawBuffer(GL_BACK);
00752 }
00753
00754
00755 Bool_t TGLViewer::SavePicture()
00756 {
00757
00758
00759
00760
00761 return SavePicture(fPictureFileName);
00762 }
00763
00764
00765 Bool_t TGLViewer::SavePicture(const TString &fileName)
00766 {
00767
00768
00769
00770
00771
00772
00773
00774 if (fileName.EndsWith(".eps"))
00775 {
00776 return TGLOutput::Capture(*this, TGLOutput::kEPS_BSP, fileName.Data());
00777 }
00778 else if (fileName.EndsWith(".pdf"))
00779 {
00780 return TGLOutput::Capture(*this, TGLOutput::kPDF_BSP, fileName.Data());
00781 }
00782 else
00783 {
00784 if (GLEW_EXT_framebuffer_object)
00785 {
00786 return SavePictureUsingFBO(fileName, fViewport.Width(), fViewport.Height(), kFALSE);
00787 }
00788 else
00789 {
00790 return SavePictureUsingBB(fileName);
00791 }
00792 }
00793 }
00794
00795
00796 Bool_t TGLViewer::SavePictureUsingBB(const TString &fileName)
00797 {
00798
00799
00800
00801
00802
00803
00804
00805 static const TString eh("TGLViewer::SavePictureUsingBB");
00806
00807 if (! fileName.EndsWith(".gif") && ! fileName.Contains(".gif+") &&
00808 ! fileName.EndsWith(".jpg") && ! fileName.EndsWith(".png"))
00809 {
00810 Warning(eh, "file %s cannot be saved with this extension.", fileName.Data());
00811 return kFALSE;
00812 }
00813
00814 if ( ! TakeLock(kDrawLock)) {
00815 Error(eh, "viewer locked - try later.");
00816 return kFALSE;
00817 }
00818
00819 TUnlocker ulck(this);
00820
00821 fLOD = TGLRnrCtx::kLODHigh;
00822 fRnrCtx->SetGrabImage(kTRUE);
00823
00824 if (!gVirtualX->IsCmdThread())
00825 gROOT->ProcessLineFast(Form("((TGLViewer *)0x%lx)->DoDraw(kFALSE)", (ULong_t)this));
00826 else
00827 DoDraw(kFALSE);
00828
00829 fRnrCtx->SetGrabImage(kFALSE);
00830
00831 glReadBuffer(GL_BACK);
00832
00833 UChar_t* xx = new UChar_t[4 * fViewport.Width() * fViewport.Height()];
00834 glPixelStorei(GL_PACK_ALIGNMENT, 1);
00835 glReadPixels(0, 0, fViewport.Width(), fViewport.Height(),
00836 GL_BGRA, GL_UNSIGNED_BYTE, xx);
00837
00838 std::auto_ptr<TImage> image(TImage::Create());
00839 image->FromGLBuffer(xx, fViewport.Width(), fViewport.Height());
00840 image->WriteImage(fileName);
00841
00842 delete [] xx;
00843
00844 return kTRUE;
00845 }
00846
00847
00848 Bool_t TGLViewer::SavePictureUsingFBO(const TString &fileName, Int_t w, Int_t h,
00849 Float_t pixel_object_scale)
00850 {
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863 static const TString eh("TGLViewer::SavePictureUsingFBO");
00864
00865 if (! fileName.EndsWith(".gif") && ! fileName.Contains(".gif+") &&
00866 ! fileName.EndsWith(".jpg") && ! fileName.EndsWith(".png"))
00867 {
00868 Warning(eh, "file %s cannot be saved with this extension.", fileName.Data());
00869 return kFALSE;
00870 }
00871
00872 if ( ! TakeLock(kDrawLock)) {
00873 Error(eh, "viewer locked - try later.");
00874 return kFALSE;
00875 }
00876
00877 TUnlocker ulck(this);
00878
00879 MakeCurrent();
00880
00881 TGLFBO *fbo = new TGLFBO();
00882 try
00883 {
00884 fbo->Init(w, h, fGLWidget->GetPixelFormat()->GetSamples());
00885 }
00886 catch (std::runtime_error& exc)
00887 {
00888 Error(eh, "%s",exc.what());
00889 return kFALSE;
00890 }
00891
00892 TGLRect old_vp(fViewport);
00893 SetViewport(0, 0, w, h);
00894
00895 Float_t old_scale = 1;
00896 if (pixel_object_scale != 0)
00897 {
00898 old_scale = fRnrCtx->GetRenderScale();
00899 fRnrCtx->SetRenderScale(old_scale * pixel_object_scale);
00900 }
00901
00902 fbo->Bind();
00903
00904 fLOD = TGLRnrCtx::kLODHigh;
00905 fRnrCtx->SetGrabImage(kTRUE);
00906
00907 if (!gVirtualX->IsCmdThread())
00908 gROOT->ProcessLineFast(Form("((TGLViewer *)0x%lx)->DoDraw(kFALSE)", (ULong_t)this));
00909 else
00910 DoDraw(kFALSE);
00911
00912 fRnrCtx->SetGrabImage(kFALSE);
00913
00914 fbo->Unbind();
00915
00916 fbo->SetAsReadBuffer();
00917
00918 UChar_t* xx = new UChar_t[4 * fViewport.Width() * fViewport.Height()];
00919 glPixelStorei(GL_PACK_ALIGNMENT, 1);
00920 glReadPixels(0, 0, fViewport.Width(), fViewport.Height(),
00921 GL_BGRA, GL_UNSIGNED_BYTE, xx);
00922
00923 std::auto_ptr<TImage> image(TImage::Create());
00924 image->FromGLBuffer(xx, fViewport.Width(), fViewport.Height());
00925 image->WriteImage(fileName);
00926
00927 delete [] xx;
00928
00929 delete fbo;
00930
00931 if (pixel_object_scale != 0)
00932 {
00933 fRnrCtx->SetRenderScale(old_scale);
00934 }
00935
00936 SetViewport(old_vp);
00937
00938 return kTRUE;
00939 }
00940
00941
00942 Bool_t TGLViewer::SavePictureWidth(const TString &fileName, Int_t width,
00943 Bool_t pixel_object_scale)
00944 {
00945
00946
00947
00948
00949 Float_t scale = Float_t(width) / fViewport.Width();
00950 Int_t height = TMath::Nint(scale*fViewport.Height());
00951
00952 return SavePictureUsingFBO(fileName, width, height, pixel_object_scale ? scale : 0);
00953 }
00954
00955
00956 Bool_t TGLViewer::SavePictureHeight(const TString &fileName, Int_t height,
00957 Bool_t pixel_object_scale)
00958 {
00959
00960
00961
00962
00963 Float_t scale = Float_t(height) / fViewport.Height();
00964 Int_t width = TMath::Nint(scale*fViewport.Width());
00965
00966 return SavePictureUsingFBO(fileName, width, height, pixel_object_scale ? scale : 0);
00967 }
00968
00969
00970 Bool_t TGLViewer::SavePictureScale (const TString &fileName, Float_t scale,
00971 Bool_t pixel_object_scale)
00972 {
00973
00974
00975
00976
00977 Int_t w = TMath::Nint(scale*fViewport.Width());
00978 Int_t h = TMath::Nint(scale*fViewport.Height());
00979
00980 return SavePictureUsingFBO(fileName, w, h, pixel_object_scale ? scale : 0);
00981 }
00982
00983
00984 void TGLViewer::DrawGuides()
00985 {
00986
00987
00988 Bool_t disabled = kFALSE;
00989 if (fReferenceOn)
00990 {
00991 glDisable(GL_DEPTH_TEST);
00992 TGLUtil::DrawReferenceMarker(*fCamera, fReferencePos);
00993 disabled = kTRUE;
00994 }
00995 if (fDrawCameraCenter)
00996 {
00997 glDisable(GL_DEPTH_TEST);
00998 Float_t radius = fCamera->ViewportDeltaToWorld(TGLVertex3(fCamera->GetCenterVec()), 3, 3).Mag();
00999 const UChar_t rgba[4] = { 0, 255, 255, 255 };
01000 TGLUtil::DrawSphere(fCamera->GetCenterVec(), radius, rgba);
01001 disabled = kTRUE;
01002 }
01003 if (fAxesDepthTest && disabled)
01004 {
01005 glEnable(GL_DEPTH_TEST);
01006 disabled = kFALSE;
01007 }
01008 else if (fAxesDepthTest == kFALSE && disabled == kFALSE)
01009 {
01010 glDisable(GL_DEPTH_TEST);
01011 disabled = kTRUE;
01012 }
01013 TGLUtil::DrawSimpleAxes(*fCamera, fOverallBoundingBox, fAxesType);
01014 if (disabled)
01015 glEnable(GL_DEPTH_TEST);
01016 }
01017
01018
01019 void TGLViewer::DrawDebugInfo()
01020 {
01021
01022
01023 if (fDebugMode)
01024 {
01025 glDisable(GL_LIGHTING);
01026 CurrentCamera().DrawDebugAids();
01027
01028
01029 glColor3d(0.0, 1.0, 0.0);
01030 fOverallBoundingBox.Draw();
01031
01032
01033 glDisable(GL_DEPTH_TEST);
01034 Double_t size = fOverallBoundingBox.Extents().Mag() / 200.0;
01035 TGLUtil::DrawSphere(TGLVertex3(0.0, 0.0, 0.0), size, TGLUtil::fgWhite);
01036 const TGLVertex3 & center = fOverallBoundingBox.Center();
01037 TGLUtil::DrawSphere(center, size, TGLUtil::fgGreen);
01038 glEnable(GL_DEPTH_TEST);
01039
01040 glEnable(GL_LIGHTING);
01041 }
01042 }
01043
01044
01045 void TGLViewer::PreDraw()
01046 {
01047
01048
01049 InitGL();
01050
01051
01052 {
01053 Color_t ci = (fGLDevice != -1) ? gPad->GetFillColor() : fRnrCtx->ColorSet().Background().GetColorIndex();
01054 TColor *color = gROOT->GetColor(ci);
01055 Float_t rgb[3];
01056 if (color)
01057 color->GetRGB(rgb[0], rgb[1], rgb[2]);
01058 else
01059 rgb[0] = rgb[1] = rgb[2] = 0.0f;
01060
01061 glClearColor(rgb[0], rgb[1], rgb[2], 0.0f);
01062 }
01063
01064 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
01065
01066 TGLUtil::CheckError("TGLViewer::PreDraw");
01067 }
01068
01069
01070 void TGLViewer::PostDraw()
01071 {
01072
01073
01074 glFlush();
01075 TGLUtil::CheckError("TGLViewer::PostDraw");
01076 }
01077
01078
01079 void TGLViewer::FadeView(Float_t alpha)
01080 {
01081
01082
01083
01084 static const Float_t z = -1.0f;
01085
01086 glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity();
01087 glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity();
01088
01089 {
01090 TGLCapabilitySwitch blend(GL_BLEND, kTRUE);
01091 TGLCapabilitySwitch light(GL_LIGHTING, kFALSE);
01092 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01093 TGLUtil::ColorAlpha(fRnrCtx->ColorSet().Background(), alpha);
01094 glBegin(GL_QUADS);
01095 glVertex3f(-1, -1, z); glVertex3f( 1, -1, z);
01096 glVertex3f( 1, 1, z); glVertex3f(-1, 1, z);
01097 glEnd();
01098 }
01099
01100 glMatrixMode(GL_PROJECTION); glPopMatrix();
01101 glMatrixMode(GL_MODELVIEW); glPopMatrix();
01102 }
01103
01104
01105 void TGLViewer::MakeCurrent() const
01106 {
01107
01108 if (fGLDevice == -1)
01109 fGLWidget->MakeCurrent();
01110 else
01111 gGLManager->MakeCurrent(fGLDevice);
01112 }
01113
01114
01115 void TGLViewer::SwapBuffers() const
01116 {
01117
01118 if ( ! IsDrawOrSelectLock()) {
01119 Error("TGLViewer::SwapBuffers", "viewer is %s", LockName(CurrentLock()));
01120 }
01121 if (fGLDevice == -1)
01122 fGLWidget->SwapBuffers();
01123 else {
01124 gGLManager->ReadGLBuffer(fGLDevice);
01125 gGLManager->Flush(fGLDevice);
01126 gGLManager->MarkForDirectCopy(fGLDevice, kFALSE);
01127 }
01128 }
01129
01130
01131 Bool_t TGLViewer::RequestSelect(Int_t x, Int_t y)
01132 {
01133
01134
01135
01136
01137
01138
01139 if ( ! TakeLock(kSelectLock)) {
01140 return kFALSE;
01141 }
01142
01143 if (!gVirtualX->IsCmdThread())
01144 return Bool_t(gROOT->ProcessLineFast(Form("((TGLViewer *)0x%lx)->DoSelect(%d, %d)", (ULong_t)this, x, y)));
01145 else
01146 return DoSelect(x, y);
01147 }
01148
01149
01150 Bool_t TGLViewer::DoSelect(Int_t x, Int_t y)
01151 {
01152
01153
01154
01155
01156
01157
01158 if (CurrentLock() != kSelectLock) {
01159 Error("TGLViewer::DoSelect", "expected kSelectLock, found %s", LockName(CurrentLock()));
01160 return kFALSE;
01161 }
01162
01163 TUnlocker ulck(this);
01164
01165 MakeCurrent();
01166
01167 fRnrCtx->BeginSelection(x, y, 3);
01168 glRenderMode(GL_SELECT);
01169
01170 PreRender();
01171 Render();
01172 PostRender();
01173
01174 Int_t nHits = glRenderMode(GL_RENDER);
01175 fRnrCtx->EndSelection(nHits);
01176
01177
01178 if (gDebug > 0) Info("TGLViewer::DoSelect", "Primary select nHits=%d.", nHits);
01179
01180 if (nHits > 0)
01181 {
01182 Int_t idx = 0;
01183 if (FindClosestRecord(fSelRec, idx))
01184 {
01185 if (fSelRec.GetTransparent())
01186 {
01187 TGLSelectRecord opaque;
01188 if (FindClosestOpaqueRecord(opaque, ++idx))
01189 fSelRec = opaque;
01190 }
01191 if (gDebug > 1) fSelRec.Print();
01192 }
01193 } else {
01194 fSelRec.Reset();
01195 }
01196
01197 ReleaseLock(kSelectLock);
01198 return ! TGLSelectRecord::AreSameSelectionWise(fSelRec, fCurrentSelRec);
01199 }
01200
01201
01202 Bool_t TGLViewer::RequestSecondarySelect(Int_t x, Int_t y)
01203 {
01204
01205
01206 if ( ! TakeLock(kSelectLock)) {
01207 return kFALSE;
01208 }
01209
01210 if (!gVirtualX->IsCmdThread())
01211 return Bool_t(gROOT->ProcessLineFast(Form("((TGLViewer *)0x%lx)->DoSecondarySelect(%d, %d)", (ULong_t)this, x, y)));
01212 else
01213 return DoSecondarySelect(x, y);
01214 }
01215
01216
01217 Bool_t TGLViewer::DoSecondarySelect(Int_t x, Int_t y)
01218 {
01219
01220
01221 if (CurrentLock() != kSelectLock) {
01222 Error("TGLViewer::DoSecondarySelect", "expected kSelectLock, found %s", LockName(CurrentLock()));
01223 return kFALSE;
01224 }
01225
01226 TUnlocker ulck(this);
01227
01228 if (! fSelRec.GetSceneInfo() || ! fSelRec.GetPhysShape() ||
01229 ! fSelRec.GetPhysShape()->GetLogical()->SupportsSecondarySelect())
01230 {
01231 if (gDebug > 0)
01232 Info("TGLViewer::SecondarySelect", "Skipping secondary selection "
01233 "(sinfo=0x%lx, pshape=0x%lx).\n",
01234 (Long_t)fSelRec.GetSceneInfo(), (Long_t)fSelRec.GetPhysShape());
01235 fSecSelRec.Reset();
01236 return kFALSE;
01237 }
01238
01239 MakeCurrent();
01240
01241 TGLSceneInfo* sinfo = fSelRec.GetSceneInfo();
01242 TGLSceneBase* scene = sinfo->GetScene();
01243 TGLPhysicalShape* pshp = fSelRec.GetPhysShape();
01244
01245 SceneInfoList_t foo;
01246 foo.push_back(sinfo);
01247 fScenes.swap(foo);
01248 fRnrCtx->BeginSelection(x, y, 3);
01249 fRnrCtx->SetSecSelection(kTRUE);
01250 glRenderMode(GL_SELECT);
01251
01252 PreRender();
01253 fRnrCtx->SetSceneInfo(sinfo);
01254 scene->PreRender(*fRnrCtx);
01255 fRnrCtx->SetDrawPass(TGLRnrCtx::kPassFill);
01256 fRnrCtx->SetShapeLOD(TGLRnrCtx::kLODHigh);
01257 glPushName(pshp->ID());
01258
01259 pshp->Draw(*fRnrCtx);
01260 glPopName();
01261 scene->PostRender(*fRnrCtx);
01262 fRnrCtx->SetSceneInfo(0);
01263 PostRender();
01264
01265 Int_t nSecHits = glRenderMode(GL_RENDER);
01266 fRnrCtx->EndSelection(nSecHits);
01267 fScenes.swap(foo);
01268
01269 if (gDebug > 0) Info("TGLViewer::DoSelect", "Secondary select nSecHits=%d.", nSecHits);
01270
01271 ReleaseLock(kSelectLock);
01272
01273 if (nSecHits > 0)
01274 {
01275 fSecSelRec = fSelRec;
01276 fSecSelRec.SetRawOnly(fRnrCtx->GetSelectBuffer()->RawRecord(0));
01277 if (gDebug > 1) fSecSelRec.Print();
01278 return kTRUE;
01279 } else {
01280 fSecSelRec.Reset();
01281 return kFALSE;
01282 }
01283 }
01284
01285
01286 void TGLViewer::ApplySelection()
01287 {
01288
01289
01290
01291
01292 fCurrentSelRec = fSelRec;
01293
01294 TGLPhysicalShape *selPhys = fSelRec.GetPhysShape();
01295 fSelectedPShapeRef->SetPShape(selPhys);
01296
01297
01298 SelectionChanged();
01299
01300 RequestDraw(TGLRnrCtx::kLODHigh);
01301 }
01302
01303
01304 Bool_t TGLViewer::RequestOverlaySelect(Int_t x, Int_t y)
01305 {
01306
01307
01308
01309
01310
01311
01312 if ( ! TakeLock(kSelectLock)) {
01313 return kFALSE;
01314 }
01315
01316 if (!gVirtualX->IsCmdThread())
01317 return Bool_t(gROOT->ProcessLineFast(Form("((TGLViewer *)0x%lx)->DoOverlaySelect(%d, %d)", (ULong_t)this, x, y)));
01318 else
01319 return DoOverlaySelect(x, y);
01320 }
01321
01322
01323 Bool_t TGLViewer::DoOverlaySelect(Int_t x, Int_t y)
01324 {
01325
01326
01327
01328 if (CurrentLock() != kSelectLock) {
01329 Error("TGLViewer::DoOverlaySelect", "expected kSelectLock, found %s", LockName(CurrentLock()));
01330 return kFALSE;
01331 }
01332
01333 TUnlocker ulck(this);
01334
01335 MakeCurrent();
01336
01337 fRnrCtx->BeginSelection(x, y, 3);
01338 glRenderMode(GL_SELECT);
01339
01340 PreRenderOverlaySelection();
01341 RenderOverlay(TGLOverlayElement::kActive, kTRUE);
01342 PostRenderOverlaySelection();
01343
01344 Int_t nHits = glRenderMode(GL_RENDER);
01345 fRnrCtx->EndSelection(nHits);
01346
01347
01348 TGLOverlayElement * selElm = 0;
01349 if (nHits > 0)
01350 {
01351 Int_t idx = 0;
01352 while (idx < nHits && FindClosestOverlayRecord(fOvlSelRec, idx))
01353 {
01354 TGLOverlayElement* el = fOvlSelRec.GetOvlElement();
01355 if (el == fCurrentOvlElm)
01356 {
01357 if (el->MouseStillInside(fOvlSelRec))
01358 {
01359 selElm = el;
01360 break;
01361 }
01362 }
01363 else if (el->MouseEnter(fOvlSelRec))
01364 {
01365 selElm = el;
01366 break;
01367 }
01368 ++idx;
01369 }
01370 }
01371 else
01372 {
01373 fOvlSelRec.Reset();
01374 }
01375
01376 ReleaseLock(kSelectLock);
01377
01378 if (fCurrentOvlElm != selElm)
01379 {
01380 if (fCurrentOvlElm) fCurrentOvlElm->MouseLeave();
01381 fCurrentOvlElm = selElm;
01382 return kTRUE;
01383 }
01384 else
01385 {
01386 return kFALSE;
01387 }
01388 }
01389
01390
01391 void TGLFaderHelper::MakeFadeStep()
01392 {
01393
01394
01395 Float_t fade = fViewer->GetFader();
01396
01397 if (fade == fFadeTarget) {
01398 delete this; return;
01399 }
01400 if (TMath::Abs(fFadeTarget - fade) < 1e-3) {
01401 fViewer->SetFader(fFadeTarget);
01402 fViewer->RequestDraw(TGLRnrCtx::kLODHigh);
01403 delete this;
01404 return;
01405 }
01406
01407 Float_t dt = fTime/fNSteps;
01408 Float_t df = (fFadeTarget - fade)/fNSteps;
01409 fViewer->SetFader(fade + df);
01410 fViewer->RequestDraw(TGLRnrCtx::kLODHigh);
01411 fTime -= dt; --fNSteps;
01412 TTimer::SingleShot(TMath::CeilNint(1000*dt),
01413 "TGLFaderHelper", this, "MakeFadeStep()");
01414 }
01415
01416
01417 void TGLViewer::AutoFade(Float_t fade, Float_t time, Int_t steps)
01418 {
01419
01420
01421
01422 TGLFaderHelper* fh = new TGLFaderHelper(this, fade, time, steps);
01423 fh->MakeFadeStep();
01424 }
01425
01426
01427 void TGLViewer::UseDarkColorSet()
01428 {
01429
01430
01431 fRnrCtx->ChangeBaseColorSet(&fDarkColorSet);
01432 RefreshPadEditor(this);
01433 }
01434
01435
01436 void TGLViewer::UseLightColorSet()
01437 {
01438
01439
01440 fRnrCtx->ChangeBaseColorSet(&fLightColorSet);
01441 RefreshPadEditor(this);
01442 }
01443
01444
01445 void TGLViewer::SwitchColorSet()
01446 {
01447
01448
01449 if (IsUsingDefaultColorSet())
01450 {
01451 Info("SwitchColorSet()", "Global color-set is in use, switch not supported.");
01452 return;
01453 }
01454
01455 if (fRnrCtx->GetBaseColorSet() == &fLightColorSet)
01456 UseDarkColorSet();
01457 else
01458 UseLightColorSet();
01459 }
01460
01461
01462 void TGLViewer::UseDefaultColorSet(Bool_t x)
01463 {
01464
01465
01466 if (x)
01467 fRnrCtx->ChangeBaseColorSet(&fgDefaultColorSet);
01468 else
01469 fRnrCtx->ChangeBaseColorSet(&fDarkColorSet);
01470 RefreshPadEditor(this);
01471 }
01472
01473
01474 Bool_t TGLViewer::IsUsingDefaultColorSet() const
01475 {
01476
01477
01478
01479 return fRnrCtx->GetBaseColorSet() == &fgDefaultColorSet;
01480 }
01481
01482
01483 void TGLViewer::SetClearColor(Color_t col)
01484 {
01485
01486
01487
01488 fRnrCtx->GetBaseColorSet()->Background().SetColor(col);
01489 }
01490
01491
01492 TGLColorSet& TGLViewer::GetDefaultColorSet()
01493 {
01494
01495
01496
01497 return fgDefaultColorSet;
01498 }
01499
01500
01501 void TGLViewer::UseDefaultColorSetForNewViewers(Bool_t x)
01502 {
01503
01504
01505
01506
01507 fgUseDefaultColorSetForNewViewers = x;
01508 }
01509
01510
01511 Bool_t TGLViewer::IsUsingDefaultColorSetForNewViewers()
01512 {
01513
01514
01515
01516
01517 return fgUseDefaultColorSetForNewViewers;
01518 }
01519
01520
01521 Bool_t TGLViewer::IsColorSetDark() const
01522 {
01523
01524
01525 return fRnrCtx->GetBaseColorSet() == &fDarkColorSet;
01526 }
01527
01528
01529
01530
01531
01532
01533 void TGLViewer::SetViewport(Int_t x, Int_t y, Int_t width, Int_t height)
01534 {
01535
01536
01537
01538
01539 if (fViewport.X() == x && fViewport.Y() == y &&
01540 fViewport.Width() == width && fViewport.Height() == height) {
01541 return;
01542 }
01543
01544 fViewport.Set(x, y, width, height);
01545 fCurrentCamera->SetViewport(fViewport);
01546
01547 if (gDebug > 2) {
01548 Info("TGLViewer::SetViewport", "updated - corner %d,%d dimensions %d,%d", x, y, width, height);
01549 }
01550 }
01551
01552 void TGLViewer::SetViewport(const TGLRect& vp)
01553 {
01554
01555
01556 SetViewport(vp.X(), vp.Y(), vp.Width(), vp.Height());
01557 }
01558
01559
01560
01561
01562
01563
01564 TGLCamera& TGLViewer::RefCamera(ECameraType cameraType)
01565 {
01566
01567
01568
01569 switch(cameraType) {
01570 case kCameraPerspXOZ:
01571 return fPerspectiveCameraXOZ;
01572 case kCameraPerspYOZ:
01573 return fPerspectiveCameraYOZ;
01574 case kCameraPerspXOY:
01575 return fPerspectiveCameraXOY;
01576 case kCameraOrthoXOY:
01577 return fOrthoXOYCamera;
01578 case kCameraOrthoXOZ:
01579 return fOrthoXOZCamera;
01580 case kCameraOrthoZOY:
01581 return fOrthoZOYCamera;
01582 case kCameraOrthoXnOY:
01583 return fOrthoXnOYCamera;
01584 case kCameraOrthoXnOZ:
01585 return fOrthoXnOZCamera;
01586 case kCameraOrthoZnOY:
01587 return fOrthoZnOYCamera;
01588 default:
01589 Error("TGLViewer::SetCurrentCamera", "invalid camera type");
01590 return *fCurrentCamera;
01591 }
01592 }
01593
01594
01595 void TGLViewer::SetCurrentCamera(ECameraType cameraType)
01596 {
01597
01598
01599
01600
01601
01602 if (IsLocked()) {
01603 Error("TGLViewer::SetCurrentCamera", "expected kUnlocked, found %s", LockName(CurrentLock()));
01604 return;
01605 }
01606
01607
01608 TGLCamera *prev = fCurrentCamera;
01609 switch (cameraType)
01610 {
01611 case kCameraPerspXOZ: {
01612 fCurrentCamera = &fPerspectiveCameraXOZ;
01613 break;
01614 }
01615 case kCameraPerspYOZ: {
01616 fCurrentCamera = &fPerspectiveCameraYOZ;
01617 break;
01618 }
01619 case kCameraPerspXOY: {
01620 fCurrentCamera = &fPerspectiveCameraXOY;
01621 break;
01622 }
01623 case kCameraOrthoXOY: {
01624 fCurrentCamera = &fOrthoXOYCamera;
01625 break;
01626 }
01627 case kCameraOrthoXOZ: {
01628 fCurrentCamera = &fOrthoXOZCamera;
01629 break;
01630 }
01631 case kCameraOrthoZOY: {
01632 fCurrentCamera = &fOrthoZOYCamera;
01633 break;
01634 }
01635 case kCameraOrthoXnOY: {
01636 fCurrentCamera = &fOrthoXnOYCamera;
01637 break;
01638 }
01639 case kCameraOrthoXnOZ: {
01640 fCurrentCamera = &fOrthoXnOZCamera;
01641 break;
01642 }
01643 case kCameraOrthoZnOY: {
01644 fCurrentCamera = &fOrthoZnOYCamera;
01645 break;
01646 }
01647 default: {
01648 Error("TGLViewer::SetCurrentCamera", "invalid camera type");
01649 break;
01650 }
01651 }
01652
01653 if (fCurrentCamera != prev)
01654 {
01655
01656 fCurrentCamera->SetViewport(fViewport);
01657 RefreshPadEditor(this);
01658
01659 if (fAutoRotator)
01660 {
01661 if (fAutoRotator->IsRunning())
01662 {
01663 fAutoRotator->Stop();
01664 }
01665 else
01666 {
01667 if (fAutoRotator->GetCamera() == fCurrentCamera)
01668 {
01669 fAutoRotator->Start();
01670 }
01671 }
01672 }
01673
01674 RequestDraw(TGLRnrCtx::kLODHigh);
01675 }
01676 }
01677
01678
01679 void TGLViewer::SetOrthoCamera(ECameraType camera,
01680 Double_t zoom, Double_t dolly,
01681 Double_t center[3],
01682 Double_t hRotate, Double_t vRotate)
01683 {
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698 switch(camera) {
01699 case kCameraOrthoXOY: {
01700 fOrthoXOYCamera.Configure(zoom, dolly, center, hRotate, vRotate);
01701 if (fCurrentCamera == &fOrthoXOYCamera) {
01702 RequestDraw(TGLRnrCtx::kLODHigh);
01703 }
01704 break;
01705 }
01706 case kCameraOrthoXOZ: {
01707 fOrthoXOZCamera.Configure(zoom, dolly, center, hRotate, vRotate);
01708 if (fCurrentCamera == &fOrthoXOZCamera) {
01709 RequestDraw(TGLRnrCtx::kLODHigh);
01710 }
01711 break;
01712 }
01713 case kCameraOrthoZOY: {
01714 fOrthoZOYCamera.Configure(zoom, dolly, center, hRotate, vRotate);
01715 if (fCurrentCamera == &fOrthoZOYCamera) {
01716 RequestDraw(TGLRnrCtx::kLODHigh);
01717 }
01718 break;
01719 }
01720 default: {
01721 Error("TGLViewer::SetOrthoCamera", "invalid camera type");
01722 break;
01723 }
01724 }
01725 }
01726
01727
01728 void TGLViewer::SetPerspectiveCamera(ECameraType camera,
01729 Double_t fov, Double_t dolly,
01730 Double_t center[3],
01731 Double_t hRotate, Double_t vRotate)
01732 {
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746 switch(camera) {
01747 case kCameraPerspXOZ: {
01748 fPerspectiveCameraXOZ.Configure(fov, dolly, center, hRotate, vRotate);
01749 if (fCurrentCamera == &fPerspectiveCameraXOZ) {
01750 RequestDraw(TGLRnrCtx::kLODHigh);
01751 }
01752 break;
01753 }
01754 case kCameraPerspYOZ: {
01755 fPerspectiveCameraYOZ.Configure(fov, dolly, center, hRotate, vRotate);
01756 if (fCurrentCamera == &fPerspectiveCameraYOZ) {
01757 RequestDraw(TGLRnrCtx::kLODHigh);
01758 }
01759 break;
01760 }
01761 case kCameraPerspXOY: {
01762 fPerspectiveCameraXOY.Configure(fov, dolly, center, hRotate, vRotate);
01763 if (fCurrentCamera == &fPerspectiveCameraXOY) {
01764 RequestDraw(TGLRnrCtx::kLODHigh);
01765 }
01766 break;
01767 }
01768 default: {
01769 Error("TGLViewer::SetPerspectiveCamera", "invalid camera type");
01770 break;
01771 }
01772 }
01773 }
01774
01775
01776 TGLAutoRotator* TGLViewer::GetAutoRotator()
01777 {
01778
01779
01780 if (fAutoRotator == 0)
01781 fAutoRotator = new TGLAutoRotator(this);
01782 return fAutoRotator;
01783 }
01784
01785
01786 void TGLViewer::SetAutoRotator(TGLAutoRotator* ar)
01787 {
01788
01789
01790 delete fAutoRotator;
01791 fAutoRotator = ar;
01792 }
01793
01794
01795
01796
01797
01798
01799
01800 void TGLViewer::GetGuideState(Int_t & axesType, Bool_t & axesDepthTest, Bool_t & referenceOn, Double_t referencePos[3]) const
01801 {
01802
01803
01804 axesType = fAxesType;
01805 axesDepthTest = fAxesDepthTest;
01806
01807 referenceOn = fReferenceOn;
01808 referencePos[0] = fReferencePos.X();
01809 referencePos[1] = fReferencePos.Y();
01810 referencePos[2] = fReferencePos.Z();
01811 }
01812
01813
01814 void TGLViewer::SetGuideState(Int_t axesType, Bool_t axesDepthTest, Bool_t referenceOn, const Double_t referencePos[3])
01815 {
01816
01817
01818 fAxesType = axesType;
01819 fAxesDepthTest = axesDepthTest;
01820 fReferenceOn = referenceOn;
01821 if (referencePos)
01822 fReferencePos.Set(referencePos[0], referencePos[1], referencePos[2]);
01823 if (fGLDevice != -1)
01824 gGLManager->MarkForDirectCopy(fGLDevice, kTRUE);
01825 RequestDraw();
01826 }
01827
01828
01829 void TGLViewer::SetDrawCameraCenter(Bool_t x)
01830 {
01831
01832
01833 fDrawCameraCenter = x;
01834 RequestDraw();
01835 }
01836
01837
01838
01839 const TGLPhysicalShape * TGLViewer::GetSelected() const
01840 {
01841
01842
01843 return fSelectedPShapeRef->GetPShape();
01844 }
01845
01846
01847
01848
01849
01850 void TGLViewer::MouseOver(TGLPhysicalShape *shape)
01851 {
01852
01853
01854 Emit("MouseOver(TGLPhysicalShape*)", (Long_t)shape);
01855 }
01856
01857
01858 void TGLViewer::MouseOver(TGLPhysicalShape *shape, UInt_t state)
01859 {
01860
01861
01862 Long_t args[2];
01863 args[0] = (Long_t)shape;
01864 args[1] = state;
01865 Emit("MouseOver(TGLPhysicalShape*,UInt_t)", args);
01866 }
01867
01868
01869 void TGLViewer::MouseOver(TObject *obj, UInt_t state)
01870 {
01871
01872
01873 Long_t args[2];
01874 args[0] = (Long_t)obj;
01875 args[1] = state;
01876 Emit("MouseOver(TObject*,UInt_t)", args);
01877 }
01878
01879
01880 void TGLViewer::ReMouseOver(TObject *obj, UInt_t state)
01881 {
01882
01883
01884 Long_t args[2];
01885 args[0] = (Long_t)obj;
01886 args[1] = state;
01887 Emit("ReMouseOver(TObject*,UInt_t)", args);
01888 }
01889
01890
01891
01892 void TGLViewer::UnMouseOver(TObject *obj, UInt_t state)
01893 {
01894
01895
01896 Long_t args[2];
01897 args[0] = (Long_t)obj;
01898 args[1] = state;
01899 Emit("UnMouseOver(TObject*,UInt_t)", args);
01900 }
01901
01902
01903 void TGLViewer::Clicked(TObject *obj)
01904 {
01905
01906
01907 Emit("Clicked(TObject*)", (Long_t)obj);
01908 }
01909
01910
01911 void TGLViewer::Clicked(TObject *obj, UInt_t button, UInt_t state)
01912 {
01913
01914
01915 Long_t args[3];
01916 args[0] = (Long_t)obj;
01917 args[1] = button;
01918 args[2] = state;
01919 Emit("Clicked(TObject*,UInt_t,UInt_t)", args);
01920 }
01921
01922
01923
01924 void TGLViewer::ReClicked(TObject *obj, UInt_t button, UInt_t state)
01925 {
01926
01927
01928 Long_t args[3];
01929 args[0] = (Long_t)obj;
01930 args[1] = button;
01931 args[2] = state;
01932 Emit("ReClicked(TObject*,UInt_t,UInt_t)", args);
01933 }
01934
01935
01936 void TGLViewer::UnClicked(TObject *obj, UInt_t button, UInt_t state)
01937 {
01938
01939
01940 Long_t args[3];
01941 args[0] = (Long_t)obj;
01942 args[1] = button;
01943 args[2] = state;
01944 Emit("UnClicked(TObject*,UInt_t,UInt_t)", args);
01945 }
01946
01947
01948 void TGLViewer::MouseIdle(TGLPhysicalShape *shape, UInt_t posx, UInt_t posy)
01949 {
01950
01951
01952 Long_t args[3];
01953 static UInt_t oldx = 0, oldy = 0;
01954
01955 if (oldx != posx || oldy != posy) {
01956 args[0] = (Long_t)shape;
01957 args[1] = posx;
01958 args[2] = posy;
01959 Emit("MouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)", args);
01960 oldx = posx;
01961 oldy = posy;
01962 }
01963 }
01964
01965
01966
01967
01968 Int_t TGLViewer::DistancetoPrimitive(Int_t , Int_t )
01969 {
01970
01971
01972
01973
01974
01975
01976 gPad->SetSelected(this);
01977 return 0;
01978 }
01979
01980
01981 void TGLViewer::ExecuteEvent(Int_t event, Int_t px, Int_t py)
01982 {
01983
01984
01985
01986
01987 if (fEventHandler)
01988 return fEventHandler->ExecuteEvent(event, px, py);
01989 }
01990
01991
01992 void TGLViewer::PrintObjects()
01993 {
01994
01995
01996 TGLOutput::Capture(*this);
01997 }
01998
01999
02000 void TGLViewer::SelectionChanged()
02001 {
02002
02003
02004 if (!fGedEditor)
02005 return;
02006
02007 TGLPhysicalShape *selected = const_cast<TGLPhysicalShape*>(GetSelected());
02008
02009 if (selected) {
02010 fPShapeWrap->fPShape = selected;
02011 fGedEditor->SetModel(fPad, fPShapeWrap, kButton1Down);
02012 } else {
02013 fPShapeWrap->fPShape = 0;
02014 fGedEditor->SetModel(fPad, this, kButton1Down);
02015 }
02016 }
02017
02018
02019 void TGLViewer::OverlayDragFinished()
02020 {
02021
02022
02023
02024 if (fGedEditor)
02025 {
02026 fGedEditor->SetModel(fPad, fGedEditor->GetModel(), kButton1Down);
02027 }
02028 }
02029
02030
02031 void TGLViewer::RefreshPadEditor(TObject* obj)
02032 {
02033
02034
02035 if (fGedEditor && (obj == 0 || fGedEditor->GetModel() == obj))
02036 {
02037 fGedEditor->SetModel(fPad, fGedEditor->GetModel(), kButton1Down);
02038 }
02039 }
02040
02041
02042 void TGLViewer::SetEventHandler(TGEventHandler *handler)
02043 {
02044
02045
02046
02047
02048
02049
02050 if (fEventHandler)
02051 delete fEventHandler;
02052
02053 fEventHandler = handler;
02054 if (fGLWidget)
02055 fGLWidget->SetEventHandler(fEventHandler);
02056 }
02057
02058
02059 void TGLViewer::RemoveOverlayElement(TGLOverlayElement* el)
02060 {
02061
02062
02063 if (el == fCurrentOvlElm)
02064 {
02065 fCurrentOvlElm = 0;
02066 }
02067 TGLViewerBase::RemoveOverlayElement(el);
02068 }
02069
02070
02071 void TGLViewer::ClearCurrentOvlElm()
02072 {
02073
02074
02075
02076
02077 if (fCurrentOvlElm)
02078 {
02079 fCurrentOvlElm->MouseLeave();
02080 fCurrentOvlElm = 0;
02081 RequestDraw();
02082 }
02083 }