#include "TGLViewerBase.h"
#include "TGLSceneBase.h"
#include "TGLSceneInfo.h"
#include <TGLRnrCtx.h>
#include "TGLCamera.h"
#include <TGLOverlay.h>
#include <TGLSelectBuffer.h>
#include <TGLSelectRecord.h>
#include <TGLUtil.h>
#include "TGLContext.h"
#include "TGLIncludes.h"
#include <algorithm>
#include <stdexcept>
ClassImp(TGLViewerBase)
TGLViewerBase::TGLViewerBase() :
fRnrCtx (0),
fCamera (0),
fClip (0),
fLOD (TGLRnrCtx::kLODHigh),
fStyle (TGLRnrCtx::kFill),
fResetSceneInfosOnRender (kFALSE),
fChanged (kFALSE)
{
fRnrCtx = new TGLRnrCtx(this);
}
TGLViewerBase::~TGLViewerBase()
{
for (SceneInfoList_i i=fScenes.begin(); i!=fScenes.end(); ++i)
{
(*i)->GetScene()->RemoveViewer(this);
delete *i;
}
delete fRnrCtx;
}
const char* TGLViewerBase::LockIdStr() const
{
return "TGLViewerBase";
}
TGLViewerBase::SceneInfoList_i
TGLViewerBase::FindScene(TGLSceneBase* scene)
{
SceneInfoList_i i = fScenes.begin();
while (i != fScenes.end() && (*i)->GetScene() != scene) ++i;
return i;
}
TGLSceneInfo* TGLViewerBase::AddScene(TGLSceneBase* scene)
{
SceneInfoList_i i = FindScene(scene);
if (i == fScenes.end()) {
TGLSceneInfo* sinfo = scene->CreateSceneInfo(this);
fScenes.push_back(sinfo);
scene->AddViewer(this);
Changed();
return sinfo;
} else {
Warning("TGLViewerBase::AddScene", "scene '%s' already in the list.",
scene->GetName());
return 0;
}
}
void TGLViewerBase::RemoveScene(TGLSceneBase* scene)
{
SceneInfoList_i i = FindScene(scene);
if (i != fScenes.end()) {
delete *i;
fScenes.erase(i);
scene->RemoveViewer(this);
Changed();
} else {
Warning("TGLViewerBase::RemoveScene", "scene '%s' not found.",
scene->GetName());
}
}
void TGLViewerBase::RemoveAllScenes()
{
for (SceneInfoList_i i=fScenes.begin(); i!=fScenes.end(); ++i)
{
TGLSceneInfo * sinfo = *i;
sinfo->GetScene()->RemoveViewer(this);
delete sinfo;
}
fScenes.clear();
Changed();
}
void TGLViewerBase::SceneDestructing(TGLSceneBase* scene)
{
SceneInfoList_i i = FindScene(scene);
if (i != fScenes.end()) {
delete *i;
fScenes.erase(i);
Changed();
} else {
Warning("TGLViewerBase::SceneDestructing", "scene not found.");
}
}
TGLSceneInfo* TGLViewerBase::GetSceneInfo(TGLSceneBase* scene)
{
SceneInfoList_i i = FindScene(scene);
if (i != fScenes.end())
return *i;
else
return 0;
}
void TGLViewerBase::AddOverlayElement(TGLOverlayElement* el)
{
fOverlay.push_back(el);
Changed();
}
void TGLViewerBase::RemoveOverlayElement(TGLOverlayElement* el)
{
std::vector<TGLOverlayElement*>::iterator it = std::find(fOverlay.begin(), fOverlay.end(), el);
if(it != fOverlay.end())
fOverlay.erase(it);
Changed();
}
void TGLViewerBase::ResetSceneInfos()
{
SceneInfoList_i i = fScenes.begin();
while (i != fScenes.end())
{
(*i)->ResetSceneStamp();
++i;
}
}
void TGLViewerBase::MergeSceneBBoxes(TGLBoundingBox& bbox)
{
bbox.SetEmpty();
for (SceneInfoList_i i=fScenes.begin(); i!=fScenes.end(); ++i)
{
TGLSceneInfo * sinfo = *i;
if (sinfo->GetActive())
{
sinfo->SetupTransformsAndBBox();
bbox.MergeAligned(sinfo->GetTransformedBBox());
}
}
}
void TGLViewerBase::PreRender()
{
TGLContextIdentity* cid = TGLContextIdentity::GetCurrent();
if (cid == 0)
{
}
else
{
if (cid != fRnrCtx->GetGLCtxIdentity())
{
if (fRnrCtx->GetGLCtxIdentity() != 0)
Warning("TGLViewerBase::PreRender", "Switching to another GL context; maybe you should use context-sharing.");
fRnrCtx->SetGLCtxIdentity(cid);
}
}
fRnrCtx->SetCamera (fCamera);
fRnrCtx->SetViewerLOD (fLOD);
fRnrCtx->SetViewerStyle (fStyle);
fRnrCtx->SetViewerClip (fClip);
if (fResetSceneInfosOnRender)
{
ResetSceneInfos();
fResetSceneInfosOnRender = kFALSE;
}
fOverallBoundingBox.SetEmpty();
SceneInfoList_t locked_scenes;
for (SceneInfoList_i i=fScenes.begin(); i!=fScenes.end(); ++i)
{
TGLSceneInfo * sinfo = *i;
if (sinfo->GetActive())
{
if ( ! sinfo->GetScene()->TakeLock(kDrawLock))
{
Warning("TGLViewerBase::PreRender", "locking of scene '%s' failed, skipping.",
sinfo->GetScene()->GetName());
continue;
}
sinfo->SetupTransformsAndBBox();
fOverallBoundingBox.MergeAligned(sinfo->GetTransformedBBox());
locked_scenes.push_back(sinfo);
}
}
fCamera->Apply(fOverallBoundingBox, fRnrCtx->GetPickRectangle());
fVisScenes.clear();
for (SceneInfoList_i i=locked_scenes.begin(); i!=locked_scenes.end(); ++i)
{
TGLSceneInfo * sinfo = *i;
const TGLBoundingBox & bbox = sinfo->GetTransformedBBox();
Bool_t visp = (!bbox.IsEmpty() && fCamera->FrustumOverlap(bbox) != kOutside);
sinfo->ViewCheck(visp);
if (visp)
fVisScenes.push_back(sinfo);
else
sinfo->GetScene()->ReleaseLock(kDrawLock);
}
}
void TGLViewerBase::Render()
{
Int_t nScenes = fVisScenes.size();
for (Int_t i = 0; i < nScenes; ++i)
{
TGLSceneInfo* sinfo = fVisScenes[i];
TGLSceneBase* scene = sinfo->GetScene();
fRnrCtx->SetSceneInfo(sinfo);
glPushName(i);
scene->FullRender(*fRnrCtx);
glPopName();
fRnrCtx->SetSceneInfo(0);
}
TGLUtil::CheckError("TGLViewerBase::Render - pre exit check");
}
void TGLViewerBase::RenderOverlay()
{
Int_t nOvl = fOverlay.size();
for (Int_t i = 0; i < nOvl; ++i)
{
TGLOverlayElement* el = fOverlay[i];
glPushName(i);
el->Render(*fRnrCtx);
glPopName();
}
}
void TGLViewerBase::PostRender()
{
Int_t nScenes = fVisScenes.size();
for (Int_t i = 0; i < nScenes; ++i)
{
fVisScenes[i]->GetScene()->ReleaseLock(kDrawLock);
}
fChanged = kFALSE;
}
void TGLViewerBase::PreRenderOverlaySelection()
{
fCamera->Apply(fOverallBoundingBox, fRnrCtx->GetPickRectangle());
}
void TGLViewerBase::PostRenderOverlaySelection()
{
}
Bool_t TGLViewerBase::ResolveSelectRecord(TGLSelectRecord& rec, Int_t recIdx)
{
TGLSelectBuffer* sb = fRnrCtx->GetSelectBuffer();
if (recIdx >= sb->GetNRecords())
return kFALSE;
sb->SelectRecord(rec, recIdx);
UInt_t sceneIdx = rec.GetItem(0);
if (sceneIdx >= fVisScenes.size())
return kFALSE;
TGLSceneInfo* sinfo = fVisScenes[sceneIdx];
rec.SetSceneInfo(sinfo);
return sinfo->GetScene()->ResolveSelectRecord(rec, 1);
}
Bool_t TGLViewerBase::FindClosestRecord(TGLSelectRecord& rec, Int_t& recIdx)
{
TGLSelectBuffer* sb = fRnrCtx->GetSelectBuffer();
while (recIdx < sb->GetNRecords())
{
if (ResolveSelectRecord(rec, recIdx))
return kTRUE;
++recIdx;
}
return kFALSE;
}
Bool_t TGLViewerBase::FindClosestOpaqueRecord(TGLSelectRecord& rec, Int_t& recIdx)
{
TGLSelectBuffer* sb = fRnrCtx->GetSelectBuffer();
while (recIdx < sb->GetNRecords())
{
if (ResolveSelectRecord(rec, recIdx) && ! rec.GetTransparent())
return kTRUE;
++recIdx;
}
return kFALSE;
}
Bool_t TGLViewerBase::FindClosestOverlayRecord(TGLOvlSelectRecord& rec,
Int_t & recIdx)
{
TGLSelectBuffer* sb = fRnrCtx->GetSelectBuffer();
while (recIdx < sb->GetNRecords())
{
sb->SelectRecord(rec, recIdx);
if (rec.GetItem(0) < fOverlay.size())
{
rec.SetOvlElement(fOverlay[rec.GetItem(0)]);
rec.NextPos();
return kTRUE;
}
++recIdx;
}
return kFALSE;
}
Last update: Thu Jan 17 08:52:30 2008
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.