// @(#)root/gl:$Name: $:$Id: TGLViewer.cxx,v 1.8 2005/06/21 16:54:17 brun Exp $
// Author: Richard Maunder 25/05/2005
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
// TODO: Function descriptions
// TODO: Class def - same as header!!!
#include "TGLViewer.h"
#include "TGLIncludes.h"
#include "TGLStopwatch.h"
#include "TGLDisplayListCache.h"
#include "TError.h"
ClassImp(TGLViewer)
//______________________________________________________________________________
TGLViewer::TGLViewer() :
fPerspectiveCamera(),
fOrthoXOYCamera(TGLOrthoCamera::kXOY),
fOrthoYOZCamera(TGLOrthoCamera::kYOZ),
fOrthoXOZCamera(TGLOrthoCamera::kXOZ),
fCurrentCamera(&fPerspectiveCamera),
fRedrawTimer(0),
fNextSceneLOD(kHigh),
fClipPlane(1.0, 0.0, 0.0, 0.0),
fUseClipPlane(kFALSE),
fDrawAxes(kFALSE),
fInitGL(kFALSE),
fDebugMode(kFALSE)
{
fRedrawTimer = new TGLRedrawTimer(*this);
}
//______________________________________________________________________________
TGLViewer::~TGLViewer()
{
}
//______________________________________________________________________________
void TGLViewer::Draw()
{
// Draw out the the current viewer/scene
// Locking mainly for Win32 mutli thread safety - but no harm in all using it
// During normal draws a draw lock is taken in other thread (Win32) in TViewerOpenGL
// to ensure thread safety. For PrintObjects repeated Draw() calls are made.
// If no draw lock taken get one now
if (fScene.CurrentLock() != TGLScene::kDrawLock) {
if (!fScene.TakeLock(TGLScene::kDrawLock)) {
Error("TGLViewer::Draw", "scene is %s", TGLScene::LockName(fScene.CurrentLock()));
}
}
TGLStopwatch timer;
UInt_t drawn = 0;
if (gDebug>2) {
timer.Start();
}
PreDraw();
// Apply current camera projection (always as scene may be empty now but rebuilt
// in which case camera must have been applied)
fCurrentCamera->Apply(fScene.BoundingBox());
// Something to draw?
if (!fScene.BoundingBox().IsEmpty()) {
// Draw axes. Still get's clipped - need to find a way to disable clips
// for this
if (fDrawAxes) {
fScene.DrawAxes();
}
// Apply any clipping plane
if (fUseClipPlane) {
glEnable(GL_CLIP_PLANE0);
glClipPlane(GL_CLIP_PLANE0, fClipPlane.CArr());
} else {
glDisable(GL_CLIP_PLANE0);
}
if (fNextSceneLOD == kHigh) {
// High quality (final pass) draws have unlimited time to complete
drawn = fScene.Draw(*fCurrentCamera, fNextSceneLOD);
} else {
// Other (interactive) draws terminate after 100 msec
drawn = fScene.Draw(*fCurrentCamera, fNextSceneLOD, 100.0);
}
// Debug mode - draw some extra boxes
if (fDebugMode) {
glDisable(GL_LIGHTING);
CurrentCamera().DrawDebugAids();
// Green scene bounding box
glColor3d(0.0, 1.0, 0.0);
fScene.BoundingBox().Draw();
glEnable(GL_LIGHTING);
}
}
PostDraw();
if (gDebug>2) {
Info("TGLViewer::Draw()", "Drew %i at %i LOD in %f msec", drawn, fNextSceneLOD, timer.End());
if (gDebug>3) {
TGLDisplayListCache::Instance().Dump();
}
}
// Release draw lock on scene
fScene.ReleaseLock(TGLScene::kDrawLock);
// Debug mode have forced rebuilds only
if (!fDebugMode) {
// Scene rebuild required?
if (!RebuildScene()) {
// Final draw pass required?
if (fNextSceneLOD != kHigh) {
fRedrawTimer->RequestDraw(100, kHigh);
}
}
}
}
//______________________________________________________________________________
void TGLViewer::PreDraw()
{
// GL work which must be done before each draw of scene
MakeCurrent();
// Initialise GL if not done
if (!fInitGL) {
InitGL();
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
TGLUtil::CheckError();
}
//______________________________________________________________________________
void TGLViewer::PostDraw()
{
// GL work which must be done after each draw of scene
SwapBuffers();
// Flush everything in case picking starts
glFlush();
TGLUtil::CheckError();
}
//______________________________________________________________________________
void TGLViewer::Invalidate(UInt_t redrawLOD)
{
fNextSceneLOD = redrawLOD;
fRedrawTimer->Stop();
}
//______________________________________________________________________________
Bool_t TGLViewer::Select(const TGLRect & rect)
{
// Select lock should already been taken in other thread in
// TViewerOpenGL::DoSelect()
if (fScene.CurrentLock() != TGLScene::kSelectLock) {
Error("TGLViewer::Draw", "expected kSelectLock, found %s", TGLScene::LockName(fScene.CurrentLock()));
return kFALSE;
}
TGLRect glRect(rect);
WindowToGL(glRect);
fCurrentCamera->Apply(fScene.BoundingBox(), &glRect);
MakeCurrent();
Bool_t changed = fScene.Select(*fCurrentCamera);
// Release select lock on scene before invalidation
fScene.ReleaseLock(TGLScene::kSelectLock);
if (changed) {
Invalidate(kHigh);
}
return changed;
}
//______________________________________________________________________________
void TGLViewer::SetViewport(Int_t x, Int_t y, UInt_t width, UInt_t height)
{
if (fScene.IsLocked()) {
Error("TGLViewer::SetViewport", "expected kUnlocked, found %s", TGLScene::LockName(fScene.CurrentLock()));
return;
}
fViewport.Set(x, y, width, height);
fCurrentCamera->SetViewport(fViewport);
Invalidate();
}
//______________________________________________________________________________
void TGLViewer::SetCurrentCamera(ECamera camera)
{
if (fScene.IsLocked()) {
Error("TGLViewer::SetCurrentCamera", "expected kUnlocked, found %s", TGLScene::LockName(fScene.CurrentLock()));
return;
}
switch(camera) {
case(kPerspective): {
fCurrentCamera = &fPerspectiveCamera;
break;
}
case(kXOY): {
fCurrentCamera = &fOrthoXOYCamera;
break;
}
case(kYOZ): {
fCurrentCamera = &fOrthoYOZCamera;
break;
}
case(kXOZ): {
fCurrentCamera = &fOrthoXOZCamera;
break;
}
default: {
assert(kFALSE);
break;
}
}
// Ensure any viewport has been propigated to the current camera
fCurrentCamera->SetViewport(fViewport);
}
//______________________________________________________________________________
void TGLViewer::SetupCameras(const TGLBoundingBox & box)
{
if (fScene.IsLocked()) {
Error("TGLViewer::SetupCameras", "expected kUnlocked, found %s", TGLScene::LockName(fScene.CurrentLock()));
return;
}
fPerspectiveCamera.Setup(box);
fOrthoXOYCamera.Setup(box);
fOrthoYOZCamera.Setup(box);
fOrthoXOZCamera.Setup(box);
}
ROOT page - Class index - Class Hierarchy - Top of the page
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.