50 ClassImp(TGLViewerBase);
54 TGLViewerBase::TGLViewerBase() :
58 fLOD (TGLRnrCtx::kLODHigh),
59 fStyle (TGLRnrCtx::kFill),
63 fResetSceneInfosOnRender (kFALSE),
68 fRnrCtx =
new TGLRnrCtx(
this);
70 fWFLineW = gEnv->GetValue(
"OpenGL.WireframeLineScalingFactor", 1.0);
71 fOLLineW = gEnv->GetValue(
"OpenGL.OutlineLineScalingFactor", 1.0);
77 TGLViewerBase::~TGLViewerBase()
79 for (SceneInfoList_i i=fScenes.begin(); i!=fScenes.end(); ++i)
81 (*i)->GetScene()->RemoveViewer(
this);
85 DeleteOverlayElements(TGLOverlayElement::kAll);
93 const char* TGLViewerBase::LockIdStr()
const
95 return "TGLViewerBase";
105 TGLViewerBase::SceneInfoList_i
106 TGLViewerBase::FindScene(TGLSceneBase* scene)
108 SceneInfoList_i i = fScenes.begin();
109 while (i != fScenes.end() && (*i)->GetScene() != scene) ++i;
116 TGLSceneInfo* TGLViewerBase::AddScene(TGLSceneBase* scene)
118 SceneInfoList_i i = FindScene(scene);
119 if (i == fScenes.end()) {
120 TGLSceneInfo* sinfo = scene->CreateSceneInfo(
this);
121 fScenes.push_back(sinfo);
122 scene->AddViewer(
this);
126 Warning(
"TGLViewerBase::AddScene",
"scene '%s' already in the list.",
135 void TGLViewerBase::RemoveScene(TGLSceneBase* scene)
137 SceneInfoList_i i = FindScene(scene);
138 if (i != fScenes.end()) {
141 scene->RemoveViewer(
this);
144 Warning(
"TGLViewerBase::RemoveScene",
"scene '%s' not found.",
152 void TGLViewerBase::RemoveAllScenes()
154 for (SceneInfoList_i i=fScenes.begin(); i!=fScenes.end(); ++i)
156 TGLSceneInfo * sinfo = *i;
157 sinfo->GetScene()->RemoveViewer(
this);
169 void TGLViewerBase::SceneDestructing(TGLSceneBase* scene)
171 SceneInfoList_i i = FindScene(scene);
172 if (i != fScenes.end()) {
177 Warning(
"TGLViewerBase::SceneDestructing",
"scene not found.");
184 TGLSceneInfo* TGLViewerBase::GetSceneInfo(TGLSceneBase* scene)
186 SceneInfoList_i i = FindScene(scene);
187 if (i != fScenes.end())
197 TGLLogicalShape* TGLViewerBase::FindLogicalInScenes(TObject*
id)
199 for (SceneInfoList_i i=fScenes.begin(); i!=fScenes.end(); ++i)
201 TGLLogicalShape *lshp = (*i)->GetScene()->FindLogical(
id);
211 void TGLViewerBase::AddOverlayElement(TGLOverlayElement* el)
213 fOverlay.push_back(el);
220 void TGLViewerBase::RemoveOverlayElement(TGLOverlayElement* el)
222 OverlayElmVec_i it = std::find(fOverlay.begin(), fOverlay.end(), el);
223 if (it != fOverlay.end())
231 void TGLViewerBase::DeleteOverlayAnnotations()
233 DeleteOverlayElements(TGLOverlayElement::kAnnotation);
239 void TGLViewerBase::DeleteOverlayElements(TGLOverlayElement::ERole role)
244 for (OverlayElmVec_i i = ovl.begin(); i != ovl.end(); ++i)
246 if (role == TGLOverlayElement::kAll || (*i)->GetRole() == role)
249 fOverlay.push_back(*i);
265 void TGLViewerBase::ResetSceneInfos()
267 SceneInfoList_i i = fScenes.begin();
268 while (i != fScenes.end())
270 (*i)->ResetSceneStamp();
278 void TGLViewerBase::MergeSceneBBoxes(TGLBoundingBox& bbox)
281 for (SceneInfoList_i i=fScenes.begin(); i!=fScenes.end(); ++i)
283 TGLSceneInfo * sinfo = *i;
284 if (sinfo->GetActive())
286 sinfo->SetupTransformsAndBBox();
287 bbox.MergeAligned(sinfo->GetTransformedBBox());
299 void TGLViewerBase::SetupClipObject()
303 fClip->Setup(fOverallBoundingBox);
311 void TGLViewerBase::PreRender()
313 TGLContextIdentity* cid = TGLContextIdentity::GetCurrent();
324 if (cid != fRnrCtx->GetGLCtxIdentity())
326 if (fRnrCtx->GetGLCtxIdentity() != 0)
327 Warning(
"TGLViewerBase::PreRender",
"Switching to another GL context; maybe you should use context-sharing.");
328 fRnrCtx->SetGLCtxIdentity(cid);
332 fRnrCtx->SetCamera (fCamera);
333 fRnrCtx->SetViewerLOD (fLOD);
334 fRnrCtx->SetViewerStyle (fStyle);
335 fRnrCtx->SetViewerWFLineW (fWFLineW);
336 fRnrCtx->SetViewerOLLineW (fOLLineW);
337 fRnrCtx->SetViewerClip (fClip);
339 if (fResetSceneInfosOnRender)
342 fResetSceneInfosOnRender = kFALSE;
345 fOverallBoundingBox.SetEmpty();
346 SceneInfoList_t locked_scenes;
347 for (SceneInfoList_i i=fScenes.begin(); i!=fScenes.end(); ++i)
349 TGLSceneInfo *sinfo = *i;
350 TGLSceneBase *scene = sinfo->GetScene();
351 if (sinfo->GetActive())
353 if ( ! fRnrCtx->Selection() || scene->GetSelectable())
355 if ( ! sinfo->GetScene()->TakeLock(kDrawLock))
357 Warning(
"TGLViewerBase::PreRender",
"locking of scene '%s' failed, skipping.",
358 sinfo->GetScene()->GetName());
361 locked_scenes.push_back(sinfo);
363 sinfo->SetupTransformsAndBBox();
364 fOverallBoundingBox.MergeAligned(sinfo->GetTransformedBBox());
368 fCamera->Apply(fOverallBoundingBox, fRnrCtx->GetPickRectangle());
374 for (SceneInfoList_i i=locked_scenes.begin(); i!=locked_scenes.end(); ++i)
376 TGLSceneInfo * sinfo = *i;
377 const TGLBoundingBox & bbox = sinfo->GetTransformedBBox();
378 Bool_t visp = (!bbox.IsEmpty() && fCamera->FrustumOverlap(bbox) != Rgl::kOutside);
379 sinfo->ViewCheck(visp);
381 fRnrCtx->SetSceneInfo(sinfo);
382 sinfo->GetScene()->PreDraw(*fRnrCtx);
383 if (sinfo->IsVisible()) {
384 fVisScenes.push_back(sinfo);
386 sinfo->GetScene()->PostDraw(*fRnrCtx);
387 sinfo->GetScene()->ReleaseLock(kDrawLock);
389 fRnrCtx->SetSceneInfo(0);
391 sinfo->GetScene()->ReleaseLock(kDrawLock);
400 void TGLViewerBase::SubRenderScenes(SubRender_foo render_foo)
402 Int_t nScenes = fVisScenes.size();
404 for (Int_t i = 0; i < nScenes; ++i)
406 TGLSceneInfo* sinfo = fVisScenes[i];
407 TGLSceneBase* scene = sinfo->GetScene();
408 fRnrCtx->SetSceneInfo(sinfo);
410 scene->PreRender(*fRnrCtx);
411 (scene->*render_foo)(*fRnrCtx);
412 scene->PostRender(*fRnrCtx);
414 fRnrCtx->SetSceneInfo(0);
423 void TGLViewerBase::Render()
432 void TGLViewerBase::RenderNonSelected()
434 SubRenderScenes(&TGLSceneBase::RenderOpaque);
436 TGLCapabilityEnabler blend(GL_BLEND, kTRUE);
437 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
438 glDepthMask(GL_FALSE);
440 SubRenderScenes(&TGLSceneBase::RenderTransp);
442 glDepthMask(GL_TRUE);
444 TGLUtil::CheckError(
"TGLViewerBase::RenderNonSelected - pre exit check");
450 void TGLViewerBase::RenderSelected()
452 SubRenderScenes(&TGLSceneBase::RenderSelOpaque);
454 TGLCapabilityEnabler blend(GL_BLEND, kTRUE);
455 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
456 glDepthMask(GL_FALSE);
458 SubRenderScenes(&TGLSceneBase::RenderSelTransp);
460 glDepthMask(GL_TRUE);
462 TGLUtil::CheckError(
"TGLViewerBase::RenderSelected - pre exit check");
468 void TGLViewerBase::RenderSelectedForHighlight()
470 fRnrCtx->SetHighlight(kTRUE);
472 SubRenderScenes(&TGLSceneBase::RenderSelOpaqueForHighlight);
474 TGLCapabilityEnabler blend(GL_BLEND, kTRUE);
475 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
476 glDepthMask(GL_FALSE);
478 SubRenderScenes(&TGLSceneBase::RenderSelTranspForHighlight);
480 glDepthMask(GL_TRUE);
482 fRnrCtx->SetHighlight(kFALSE);
488 void TGLViewerBase::RenderOpaque(Bool_t rnr_non_selected, Bool_t rnr_selected)
490 if (rnr_non_selected)
492 SubRenderScenes(&TGLSceneBase::RenderOpaque);
496 SubRenderScenes(&TGLSceneBase::RenderSelOpaque);
499 TGLUtil::CheckError(
"TGLViewerBase::RenderOpaque - pre exit check");
505 void TGLViewerBase::RenderTransparent(Bool_t rnr_non_selected, Bool_t rnr_selected)
507 TGLCapabilityEnabler blend(GL_BLEND, kTRUE);
508 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
509 glDepthMask(GL_FALSE);
511 if (rnr_non_selected)
513 SubRenderScenes(&TGLSceneBase::RenderTransp);
517 SubRenderScenes(&TGLSceneBase::RenderSelTransp);
520 glDepthMask(GL_TRUE);
522 TGLUtil::CheckError(
"TGLViewerBase::RenderTransparent - pre exit check");
528 void TGLViewerBase::RenderOverlay(Int_t state, Bool_t selection)
530 Int_t nOvl = fOverlay.size();
531 for (Int_t i = 0; i < nOvl; ++i)
533 TGLOverlayElement* el = fOverlay[i];
534 if (el->GetState() & state)
536 if (selection) glPushName(i);
537 el->Render(*fRnrCtx);
538 if (selection) glPopName();
547 void TGLViewerBase::PostRender()
549 for (SceneInfoVec_i i = fVisScenes.begin(); i != fVisScenes.end(); ++i)
551 TGLSceneInfo* sinfo = *i;
552 fRnrCtx->SetSceneInfo(sinfo);
553 sinfo->GetScene()->PostDraw(*fRnrCtx);
554 fRnrCtx->SetSceneInfo(0);
555 sinfo->GetScene()->ReleaseLock(kDrawLock);
566 void TGLViewerBase::PreRenderOverlaySelection()
568 fCamera->Apply(fOverallBoundingBox, fRnrCtx->GetPickRectangle());
574 void TGLViewerBase::PostRenderOverlaySelection()
601 Bool_t TGLViewerBase::ResolveSelectRecord(TGLSelectRecord& rec, Int_t recIdx)
603 TGLSelectBuffer* sb = fRnrCtx->GetSelectBuffer();
604 if (recIdx >= sb->GetNRecords())
607 if (sb->SelectRecord(rec, recIdx) < 1)
610 UInt_t sceneIdx = rec.GetItem(0);
611 if (sceneIdx >= fVisScenes.size())
614 TGLSceneInfo* sinfo = fVisScenes[sceneIdx];
615 rec.SetSceneInfo(sinfo);
616 return sinfo->GetScene()->ResolveSelectRecord(rec, 1);
624 Bool_t TGLViewerBase::FindClosestRecord(TGLSelectRecord& rec, Int_t& recIdx)
626 TGLSelectBuffer* sb = fRnrCtx->GetSelectBuffer();
628 while (recIdx < sb->GetNRecords())
630 if (ResolveSelectRecord(rec, recIdx))
642 Bool_t TGLViewerBase::FindClosestOpaqueRecord(TGLSelectRecord& rec, Int_t& recIdx)
644 TGLSelectBuffer* sb = fRnrCtx->GetSelectBuffer();
646 while (recIdx < sb->GetNRecords())
648 if (ResolveSelectRecord(rec, recIdx) && ! rec.GetTransparent())
660 Bool_t TGLViewerBase::FindClosestOverlayRecord(TGLOvlSelectRecord& rec,
663 TGLSelectBuffer* sb = fRnrCtx->GetSelectBuffer();
665 while (recIdx < sb->GetNRecords())
667 sb->SelectRecord(rec, recIdx);
668 if (rec.GetItem(0) < fOverlay.size())
670 rec.SetOvlElement(fOverlay[rec.GetItem(0)]);