TGLRnrCtx.cxx

Go to the documentation of this file.
00001 // @(#)root/gl:$Id: TGLRnrCtx.cxx 34006 2010-06-21 10:36:05Z matevz $
00002 // Author:  Matevz Tadel, Feb 2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "TVirtualX.h"
00013 #include "TString.h"
00014 #include "TROOT.h"
00015 
00016 #include "TGLRnrCtx.h"
00017 #include "TGLSceneInfo.h"
00018 #include "TGLSelectBuffer.h"
00019 #include "TGLIncludes.h"
00020 #include "TGLUtil.h"
00021 #include "TGLCamera.h"
00022 #include "TGLFontManager.h"
00023 #include "TGLContext.h"
00024 
00025 #include "TError.h"
00026 #include "TMathBase.h"
00027 #include "TMath.h"
00028 
00029 #include <list>
00030 #include <algorithm>
00031 #include <cassert>
00032 
00033 //______________________________________________________________________
00034 //
00035 // The TGLRnrCtx class aggregates data for a given redering context as
00036 // needed by various parts of the ROOT's OpenGL infractructure. It
00037 // serves as a connecting point between the steering part of the
00038 // infrastructure (viewer, scene) and concrete rendering classes
00039 // (logical, physical shape). It is just a data-holder, there is no
00040 // functionality in it.
00041 //
00042 // Development notes:
00043 //
00044 // One RnrCtx is created by each viewer and it is just an extension of
00045 // the viewer context that changes along the render
00046 // descend. Separating this also has some abstract benefit of hiding
00047 // viewer implementation from those that do not need to know it.
00048 //
00049 // Current scene / scene-info part is always initialized by viewer,
00050 // scenes can assume they're ok.
00051 
00052 
00053 ClassImp(TGLRnrCtx);
00054 
00055 //______________________________________________________________________
00056 TGLRnrCtx::TGLRnrCtx(TGLViewerBase* viewer) :
00057    fViewer    (viewer),
00058    fCamera    (0),
00059    fSceneInfo (0),
00060 
00061    fViewerLOD    (kLODUndef),
00062    fSceneLOD     (kLODUndef),
00063    fCombiLOD     (kLODUndef),
00064    fShapeLOD     (kLODUndef),
00065    fShapePixSize (0),
00066 
00067    fViewerStyle  (kStyleUndef),
00068    fSceneStyle   (kStyleUndef),
00069 
00070    fViewerWFLineW (0),
00071    fSceneWFLineW  (0),
00072    fViewerOLLineW (0),
00073    fSceneOLLineW  (0),
00074 
00075    fViewerClip   (0),
00076    fSceneClip    (0),
00077    fClip         (0),
00078    fDrawPass     (kPassUndef),
00079 
00080    fStopwatch    (),
00081    fRenderTimeOut(0.0),
00082    fIsRunning    (kFALSE),
00083    fHasTimedOut  (kFALSE),
00084 
00085    fHighlight    (kFALSE),  fHighlightOutline (kFALSE),
00086    fSelection    (kFALSE),  fSecSelection     (kFALSE),
00087    fPickRadius   (0),
00088    fPickRectangle(0),
00089    fSelectBuffer (0),
00090 
00091    fColorSetStack(0),
00092    fRenderScale  (1),
00093 
00094    fEventKeySym  (0),
00095 
00096    fDLCaptureOpen (kFALSE),
00097    fGLCtxIdentity (0),
00098    fQuadric       (0),
00099 
00100    fGrabImage     (kFALSE),
00101    fGrabBuffer    (-1),
00102    fGrabbedImage  (0)
00103 {
00104    // Constructor.
00105 
00106    
00107    fColorSetStack = new lpTGLColorSet_t;
00108    fColorSetStack->push_back(0);
00109 
00110    fSelectBuffer = new TGLSelectBuffer;
00111    fQuadric = gluNewQuadric();
00112    gluQuadricOrientation(fQuadric, (GLenum)GLU_OUTSIDE);
00113    gluQuadricNormals    (fQuadric, (GLenum)GLU_SMOOTH);
00114 
00115    if (fViewer == 0)
00116    {
00117       // Assume external usage, initialize for highest quality.
00118       fViewerLOD = fSceneLOD = fCombiLOD = fShapeLOD = kLODHigh;
00119       fViewerStyle = fSceneStyle = kFill;
00120       fDrawPass = kPassFill;
00121    }
00122 }
00123 
00124 //______________________________________________________________________
00125 TGLRnrCtx::~TGLRnrCtx()
00126 {
00127    // Destructor.
00128 
00129    gluDeleteQuadric(fQuadric);
00130    delete fPickRectangle;
00131    delete fSelectBuffer;
00132    delete fColorSetStack;
00133 }
00134 
00135 //______________________________________________________________________
00136 TGLSceneBase * TGLRnrCtx::GetScene()
00137 {
00138    // Return current scene (based on scene-info data).
00139 
00140    return  fSceneInfo->GetScene();
00141 }
00142 
00143 //______________________________________________________________________
00144 TGLSceneBase & TGLRnrCtx::RefScene()
00145 {
00146    // Return current scene (based on scene-info data).
00147 
00148    return *fSceneInfo->GetScene();
00149 }
00150 
00151 /**************************************************************************/
00152 
00153 //______________________________________________________________________
00154 Bool_t TGLRnrCtx::IsDrawPassFilled() const
00155 {
00156    // Returns true if current render-pass uses filled polygon style.
00157 
00158    return fDrawPass == kPassFill || fDrawPass == kPassOutlineFill;
00159 }
00160 
00161 
00162 /******************************************************************************/
00163 // Stopwatch
00164 /******************************************************************************/
00165 
00166 //______________________________________________________________________________
00167 void TGLRnrCtx:: StartStopwatch()
00168 {
00169    // Start the stopwatch.
00170 
00171    if (fIsRunning)
00172       return;
00173 
00174    fStopwatch.Start();
00175    fIsRunning   = kTRUE;
00176    fHasTimedOut = kFALSE;
00177 }
00178 
00179 //______________________________________________________________________________
00180 void TGLRnrCtx:: StopStopwatch()
00181 {
00182    // Stop the stopwatch.
00183 
00184    fHasTimedOut = fStopwatch.End() > fRenderTimeOut;
00185    fIsRunning = kFALSE;
00186 }
00187 
00188 //______________________________________________________________________________
00189 Bool_t TGLRnrCtx::HasStopwatchTimedOut()
00190 {
00191    // Check if the stopwatch went beyond the render time limit.
00192 
00193    if (fHasTimedOut) return kTRUE;
00194    if (fIsRunning && fStopwatch.Lap() > fRenderTimeOut)
00195       fHasTimedOut = kTRUE;
00196    return fHasTimedOut;
00197 }
00198 
00199 
00200 /******************************************************************************/
00201 // Selection & picking
00202 /******************************************************************************/
00203 
00204 //______________________________________________________________________________
00205 void TGLRnrCtx::BeginSelection(Int_t x, Int_t y, Int_t r)
00206 {
00207    // Setup context for running selection.
00208    // x and y are in window coordinates.
00209 
00210    fSelection    = kTRUE;
00211    fSecSelection = kFALSE;
00212    fPickRadius   = r;
00213    if (!fPickRectangle) fPickRectangle = new TGLRect;
00214    fPickRectangle->Set(x, y, r, r);
00215 
00216    glSelectBuffer(fSelectBuffer->GetBufSize(), fSelectBuffer->GetBuf());
00217 }
00218 
00219 //______________________________________________________________________________
00220 void TGLRnrCtx::EndSelection(Int_t glResult)
00221 {
00222    // End selection.
00223 
00224    fSelection    = kFALSE;
00225    fSecSelection = kFALSE;
00226    fPickRadius   = 0;
00227    delete fPickRectangle; fPickRectangle = 0;
00228 
00229    if (glResult < 0)
00230    {
00231       if (fSelectBuffer->CanGrow() && fSelectBuffer->GetBufSize() > 0x10000)
00232       {
00233          Warning("TGLRnrCtx::EndSelection",
00234                  "Select buffer size (%d) insufficient, doubling it.",
00235                  fSelectBuffer->GetBufSize());
00236          fSelectBuffer->Grow();
00237       }
00238       else
00239       {
00240          Warning("TGLRnrCtx::EndSelection",
00241                  "Select buffer size (%d) insufficient. This is maximum.",
00242                  fSelectBuffer->GetBufSize());
00243       }
00244    }
00245    fSelectBuffer->ProcessResult(glResult);
00246 }
00247 
00248 //______________________________________________________________________________
00249 TGLRect * TGLRnrCtx::GetPickRectangle()
00250 {
00251    // Return current pick rectangle. This is *zero* when
00252    // selection is not set.
00253 
00254    return fPickRectangle;
00255 }
00256 
00257 //______________________________________________________________________________
00258 Int_t TGLRnrCtx::GetPickRadius()
00259 {
00260    // Return pick radius. If selection is not active it returns 0.
00261 
00262    return fPickRadius;
00263 }
00264 
00265 
00266 /**************************************************************************/
00267 // ColorSet access & management
00268 /******************************************************************************/
00269 
00270 //______________________________________________________________________________
00271 void TGLRnrCtx::PushColorSet()
00272 {
00273    // Create copy of current color-set on the top of the stack.
00274 
00275    fColorSetStack->push_back(new TGLColorSet(*fColorSetStack->back()));
00276 }
00277 
00278 //______________________________________________________________________________
00279 TGLColorSet& TGLRnrCtx::ColorSet()
00280 {
00281    // Return reference to current color-set (top of hte stack).
00282 
00283    return * fColorSetStack->back();
00284 }
00285 
00286 //______________________________________________________________________________
00287 void TGLRnrCtx::PopColorSet()
00288 {
00289    // Pops the top-most color-set.
00290    // If only one entry is available, error is printed and the entry remains.
00291 
00292    if (fColorSetStack->size() >= 2)
00293    {
00294       delete fColorSetStack->back();
00295       fColorSetStack->pop_back();
00296    }
00297    else
00298    {
00299       Error("PopColorSet()", "Attempting to remove the last entry.");
00300    }
00301 }
00302 
00303 //______________________________________________________________________________
00304 TGLColorSet* TGLRnrCtx::ChangeBaseColorSet(TGLColorSet* set)
00305 {
00306    // Change the default/bottom color-set.
00307    // Returns the previous color-set.
00308 
00309    TGLColorSet* old = fColorSetStack->front();
00310    fColorSetStack->front() = set;
00311    return old;
00312 }
00313 
00314 //______________________________________________________________________________
00315 TGLColorSet* TGLRnrCtx::GetBaseColorSet()
00316 {
00317    // Returns the current base color-set.
00318 
00319    return fColorSetStack->front();
00320 }
00321 
00322 //______________________________________________________________________________
00323 void TGLRnrCtx::ColorOrForeground(Color_t col)
00324 {
00325    // Set col if it is different from background, otherwise use
00326    // current foreground color.
00327 
00328    if (fColorSetStack->back()->Background().GetColorIndex() == col)
00329       TGLUtil::Color(fColorSetStack->back()->Foreground());
00330    else
00331       TGLUtil::Color(col);
00332 }
00333 
00334 /**************************************************************************/
00335 // Display-list state
00336 /******************************************************************************/
00337 
00338 //______________________________________________________________________
00339 void TGLRnrCtx::OpenDLCapture()
00340 {
00341    // Start display-list capture.
00342 
00343    assert(fDLCaptureOpen == kFALSE);
00344    fDLCaptureOpen = kTRUE;
00345 }
00346 
00347 //______________________________________________________________________
00348 void TGLRnrCtx::CloseDLCapture()
00349 {
00350    // End display list capture.
00351 
00352    assert(fDLCaptureOpen == kTRUE);
00353    fDLCaptureOpen = kFALSE;
00354 }
00355 
00356 
00357 /******************************************************************************/
00358 // TGLFont interface
00359 /******************************************************************************/
00360 //______________________________________________________________________
00361 void TGLRnrCtx::ReleaseFont(TGLFont& font)
00362 {
00363    // Release font in the GL rendering context.
00364 
00365    fGLCtxIdentity->GetFontManager()->ReleaseFont(font);
00366 }
00367 
00368 //______________________________________________________________________
00369 void TGLRnrCtx::RegisterFontNoScale(Int_t size, Int_t file, Int_t mode, TGLFont& out)
00370 {
00371    // Get font in the GL rendering context.
00372 
00373    fGLCtxIdentity->GetFontManager()->RegisterFont( size, file, (TGLFont::EMode)mode, out);
00374 }
00375 
00376 //______________________________________________________________________
00377 void TGLRnrCtx::RegisterFontNoScale(Int_t size, const char* name, Int_t mode, TGLFont& out)
00378 {
00379    // Get font in the GL rendering context.
00380 
00381    fGLCtxIdentity->GetFontManager()->RegisterFont(size, name, (TGLFont::EMode)mode, out);
00382 }
00383 
00384 //______________________________________________________________________
00385 void TGLRnrCtx::RegisterFont(Int_t size, Int_t file, Int_t mode, TGLFont& out)
00386 {
00387    // Get font in the GL rendering context.
00388    // The font is scaled relative to current render scale.
00389 
00390   RegisterFontNoScale(TMath::Nint(size*fRenderScale), file, mode, out);
00391 }
00392 
00393 //______________________________________________________________________
00394 void TGLRnrCtx::RegisterFont(Int_t size, const char* name, Int_t mode, TGLFont& out)
00395 {
00396    // Get font in the GL rendering context.
00397    // The font is scaled relative to current render scale.
00398 
00399   RegisterFontNoScale(TMath::Nint(size*fRenderScale), name, mode, out);
00400 }
00401 
00402 
00403 /******************************************************************************/
00404 // Matrix manipulation helpers
00405 /******************************************************************************/
00406 
00407 void TGLRnrCtx::ProjectionMatrixPushIdentity()
00408 {
00409    glMatrixMode(GL_PROJECTION);
00410    glPushMatrix();
00411    glLoadIdentity();
00412    if (Selection())
00413    {
00414       TGLRect rect(*GetPickRectangle());
00415       GetCamera()->WindowToViewport(rect);
00416       gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(),
00417                     (Int_t*) GetCamera()->RefViewport().CArr());
00418    }
00419    glMatrixMode(GL_MODELVIEW);
00420 }
00421 
00422 void TGLRnrCtx::ProjectionMatrixPop()
00423 {
00424    glMatrixMode(GL_PROJECTION);
00425    glPopMatrix();
00426    glMatrixMode(GL_MODELVIEW);
00427 }
00428 
00429 
00430 /**************************************************************************/
00431 // Static helpers
00432 /**************************************************************************/
00433 
00434 //______________________________________________________________________________
00435 const char* TGLRnrCtx::StyleName(Short_t style)
00436 {
00437    // Return string describing the style.
00438 
00439    switch (style)
00440    {
00441       case TGLRnrCtx::kFill:       return "Filled Polys";
00442       case TGLRnrCtx::kWireFrame:  return "Wireframe";
00443       case TGLRnrCtx::kOutline:    return "Outline";
00444       default:                     return "Oogaa-dooga style";
00445    }
00446 }

Generated on Tue Jul 5 14:18:08 2011 for ROOT_528-00b_version by  doxygen 1.5.1