vrj::PfDrawManager Class Reference

Concrete singleton class for API-specific Draw Manager for OpenGL Performer. More...

#include <vrj/Draw/Pf/PfDrawmanager.h>

Inheritance diagram for vrj::PfDrawManager:

Inheritance graph
[legend]
Collaboration diagram for vrj::PfDrawManager:

Collaboration graph
[legend]
List of all members.

Public Member Functions

virtual void sync ()
 Blocks until the end of the frame.
virtual void draw ()
 
Postcondition:
Calls pfFrame()

pfScene * getRootWithSim ()
 Returns the Simulator SceneGraph so that PfBasicSimulator can add/update the Head and Wand.
virtual void setApp (App *_app)
 Sets the app the draw whould interact with.
virtual void initAPI ()
 
Postcondition:
Calls pfInit() and sets up the system.

void initChanGroupAttribs (pfChannel *masterChan)
 Initializes the parameters of the master channel.
virtual void addDisplay (Display *disp)
 Callback when display is added to display manager.
virtual void removeDisplay (Display *disp)
 Callback when display is removed to display manager.
virtual void closeAPI ()
 Shuts down the drawing API.
virtual void updatePfProjections ()
 Updates all the projections for the displays.
void debugDump (int debugLevel)
 Helper function that finds the pfDisp given a channel.
void debugDumpPfDisp (pfDisplay *pf_disp, int debugLevel)
virtual bool configCanHandle (jccl::ConfigElementPtr element)
 Can the handler handle the given element?

Protected Member Functions

virtual bool configAdd (jccl::ConfigElementPtr element)
 Adds the element to the configuration.
virtual bool configRemove (jccl::ConfigElementPtr element)
 Removes the element from the current configuration.
bool configDisplaySystem (jccl::ConfigElementPtr element)
 Sets up display system related attributes.
void callAppChanFuncs ()
 Calls all the application channel callbacks.
void updatePfProjection (pfChannel *chan, Projection *proj)
 
Postcondition:
chan has its view matrix set to the Performer.

void initPerformerGraph ()
 Helper function to create the base scene graph stuff.
void initAppGraph ()
 Helper that (re)loads the application's scene graph into the active scene(s).
void initPipes ()
 Initializes all the pipes that may need to be used.
pfPipe * getPfPipe (unsigned pipe_num)
 Gets a Performer pipe.
std::vector< int > getMonoFBConfig (vrj::Display *disp)
 Returns the needed mono frame buffer config.
std::vector< int > getStereoFBConfig (vrj::Display *disp)
 Returns the needed stereo frame buffer config.
void configFrameBuffer (vrj::Display *disp, std::vector< int > &attrs)
 Adds frame buffer configuration options to the given vector based on the given vrj::Display object's OpenGL frame buffer configuration.
 PfDrawManager ()
virtual ~PfDrawManager ()
 vprSingletonHeader (PfDrawManager)
Display helpers
Helpers for releasing a display and the associated cruft.

void releaseDisplay (pfDisplay &disp)
void releaseViewport (pfDisplay &disp, pfViewport &vp)
pfPipeWindow * allocatePipeWin (unsigned pipeNum)
void releasePipeWin (pfPipeWindow *pipeWin, unsigned pipeNum)

Protected Attributes

unsigned int mNumPipes
 The number of Performer pipes.
std::vector< pfPipe * > mPipes
 Performer pipes we have opened.
std::vector< std::string > mPipeStrs
 The X11 names of the pipes.
bool mPfHasForked
 Performer has forked its processes already.
std::vector< std::vector<
pfPipeWindow * > > 
mPipeWindows
 List of (available) pipe windows grouped by pipe num.
Performer State
PfAppmApp
 The user application.
std::vector< pfDisplaymDisplays
 All Performer displays.
std::vector< PfInputHandler * > mPfInputHandlers
 Input Handlers for all Performer windows.
std::vector< pfChannel * > mSurfChannels
std::vector< pfChannel * > mSimChannels
 List of sim displays.
pfChannel * mSurfMasterChan
 Master channel.
pfChannel * mSimMasterChan
 Master channel for simulators.
Scene graph nodes
       mRoot
        |
     mSceneGroup -- mSceneRoot -- app scene
       /
 mRootWithSim   mHeadDCS
       \       /
       mSimTree
              |
              mWandDCS
 


pfScene * mRoot
 Root of performer tree to render.
pfGroup * mSceneRoot
 Root of scene to render (changes at run-time).
pfGroup * mSceneGroup
 The group node with only sceneRoot under it.
pfScene * mRootWithSim
 The root with the simulator group & the sceneRoot.

Friends

void PFconfigPWin (pfPipeWindow *pWin)
void PfDrawFunc (pfChannel *chan, void *chandata, bool left_eye, bool right_eye, bool stereo)
void PfAppFunc (pfChannel *chan, void *chandata)

Classes

struct  pfDisplay
struct  pfDisplay_disp
struct  pfViewport
 The channels associated with a viewport. More...

Detailed Description

Concrete singleton class for API-specific Draw Manager for OpenGL Performer.

Responsible for all Performer rendering and windowing.

Definition at line 77 of file PfDrawManager.h.


Constructor & Destructor Documentation

vrj::PfDrawManager::PfDrawManager (  )  [inline, protected]

Definition at line 364 of file PfDrawManager.h.

00365       : mApp(NULL)
00366       , mSurfMasterChan(NULL)
00367       , mSimMasterChan(NULL)
00368       , mPfHasForked(false)
00369       , mRoot(NULL)
00370       , mSceneRoot(NULL)
00371       , mSceneGroup(NULL)
00372       , mRootWithSim(NULL)
00373    {;}

vrj::PfDrawManager::~PfDrawManager (  )  [protected, virtual]

Definition at line 93 of file PfDrawManager.cpp.

References mPfInputHandlers.

00094 {
00095    //TODO: Add thread safety.
00096    for ( std::vector<PfInputHandler*>::iterator itr = mPfInputHandlers.begin();
00097          itr != mPfInputHandlers.end() ; itr++)
00098    {
00099       delete *itr;
00100    }
00101    mPfInputHandlers.clear();
00102 }


Member Function Documentation

void vrj::PfDrawManager::sync (  )  [virtual]

Blocks until the end of the frame.

Precondition:
None.
Postcondition:
The frame has been drawn.

Implements vrj::DrawManager.

Definition at line 156 of file PfDrawManager.cpp.

References vrjDBG_DRAW_MGR().

00157 {
00158    vprDEBUG(vrjDBG_DRAW_MGR,vprDBG_VERB_LVL)
00159       << "vrj::PfDrawManager::sync\n" << vprDEBUG_FLUSH;
00160    pfSync();
00161 }

void vrj::PfDrawManager::draw (  )  [virtual]

Postcondition:
Calls pfFrame()

Precondition:
None.
Postcondition:
Frame has been triggered to begin drawing.

Implements vrj::DrawManager.

Definition at line 166 of file PfDrawManager.cpp.

References callAppChanFuncs(), mPfInputHandlers, and updatePfProjections().

00167 {
00168    vprDEBUG(vprDBG_ALL,vprDBG_VERB_LVL)
00169       << "[vrj::PfDrawManager::draw()] calling appChanFuncs\n"
00170       << vprDEBUG_FLUSH;
00171    callAppChanFuncs();
00172 
00173    updatePfProjections();
00174 
00175    vprDEBUG(vprDBG_ALL,vprDBG_VERB_LVL)
00176       << "[vrj::PfDrawManager::draw] calling pfFrame()\n" << vprDEBUG_FLUSH;
00177 
00178    pfFrame();
00179 
00180    for (std::vector<PfInputHandler*>::iterator itr = mPfInputHandlers.begin() ;
00181         itr != mPfInputHandlers.end() ; itr++)
00182    {
00183       (*itr)->checkEvents();
00184    }
00185 }

pfScene* vrj::PfDrawManager::getRootWithSim (  )  [inline]

Returns the Simulator SceneGraph so that PfBasicSimulator can add/update the Head and Wand.

Definition at line 153 of file PfDrawManager.h.

00154    {
00155       return mRootWithSim;
00156    }

void vrj::PfDrawManager::setApp ( App _app  )  [virtual]

Sets the app the draw whould interact with.

Precondition:
None
Postcondition:
self'.app = _app

Implements vrj::DrawManager.

Definition at line 213 of file PfDrawManager.cpp.

References initAppGraph(), mApp, and mPfHasForked.

00214 {
00215    //vprASSERT(app != NULL);
00216    mApp = dynamic_cast<PfApp*>(_app);
00217    if(mPfHasForked)
00218       initAppGraph();         // If pf is already started, then intialize the app scene graph
00219 
00220 }

void vrj::PfDrawManager::initAPI (  )  [virtual]

Postcondition:
Calls pfInit() and sets up the system.

We should call pfInit().

Configure process model.
Configure multi-pipe model.
Then call pfConfig to start the MP stuff.
Sets up channels and pWins.

Note:
Fork happens here.

Implements vrj::DrawManager.

Definition at line 228 of file PfDrawManager.cpp.

References configDisplaySystem(), vrj::DisplayManager::getDisplaySystemElement(), initAppGraph(), initPerformerGraph(), initPipes(), mApp, vrj::DrawManager::mDisplayManager, mNumPipes, mPfHasForked, mRoot, mRootWithSim, mSceneRoot, vrj::PfApp::preForkInit(), and vrjDBG_DRAW_MGR().

00229 {
00230    pfInit();
00231    pfuInitUtil();
00232    
00233    // XXX: This call should really be triggered by a change in draw manager or something
00234    vprASSERT(mDisplayManager != NULL);
00235    configDisplaySystem(mDisplayManager->getDisplaySystemElement());    // Configure all the display system stuff
00236 
00237    mApp->preForkInit();
00238 
00239    vprDEBUG_BEGIN(vrjDBG_DRAW_MGR,vprDBG_STATE_LVL)
00240       << "[vrj::PfDrawManager::initAPI()] Entering." << std::endl
00241       << vprDEBUG_FLUSH;
00242 
00243    // Set params for Multi-pipe and Multiprocess
00244    pfMultipipe(mNumPipes);
00245 
00246 #ifdef VPR_OS_Linux
00247    // Multi-processing with Performer on SMP Linux machines is unstable, and
00248    // there is not much of a performance gain to splitting App, Cull, and Draw
00249    // up among multiple processes on a single-processor machine.
00250    pfMultiprocess(PFMP_APPCULLDRAW);
00251 #else
00252    // If we are running in a cluster then we must run in single process mode.
00253    if(jccl::ConfigManager::instance()->isElementTypeInPendingList("cluster_manager") ||
00254       jccl::ConfigManager::instance()->isElementTypeInActiveList("cluster_manager"))
00255    {
00256       vprDEBUG_BEGIN(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL)
00257          << "PfDrawManager::initAPI() Running Performer in single process to ensure cluster synchronization."
00258          << std::endl << vprDEBUG_FLUSH;
00259       // Single process mode.
00260       pfMultiprocess(PFMP_APPCULLDRAW);
00261    }
00262    else
00263    {
00264       // Multiple process mode.
00265       pfMultiprocess(PFMP_APP_CULL_DRAW);
00266    }
00267 #endif
00268 
00269 // We can not init head and wand model loaders since they are loaded in PfBasicSimInterface
00270 //   initLoaders();          // Must call before pfConfig
00271 
00272    // --- FORKS HERE --- //
00273    pfConfig();
00274    
00275    // Initialize shared memory for utility libraries
00276    pfuInit();
00277 
00278    mPfHasForked = true;
00279 
00280    // Initialize the pipes that the system may need
00281    // If we don't do this, then pf automatically give each pipe a big black channel
00282    initPipes();
00283 
00284    initPerformerGraph();        // Create the other scene graph nodes
00285    if(mApp != NULL)
00286       initAppGraph();           // App was already set, but pf was not loaded.  So load graph now
00287 
00288 
00289    vprASSERT(mRoot != NULL && "We have a NULL root in PfDrawManager");
00290    vprASSERT(mRootWithSim != NULL && "We have a NULL sim root scene in PfDrawManager");
00291    vprASSERT(mSceneRoot != NULL && "We have a NULL root scene in PfDrawManager");
00292 
00293    //pfFrame();
00294 
00295    // Dump the state
00296    // debugDump(vprDBG_CONFIG_LVL);
00297 
00298    vprDEBUG_END(vrjDBG_DRAW_MGR,vprDBG_STATE_LVL)
00299       << "[vrj::PfDrawManager::initAPI()] Exiting." << std::endl
00300       << vprDEBUG_FLUSH;
00301 }

void vrj::PfDrawManager::initChanGroupAttribs ( pfChannel *  masterChan  ) 

Initializes the parameters of the master channel.

Definition at line 838 of file PfDrawManager.cpp.

Referenced by addDisplay().

00839 {
00840    //masterChan->setNearFar(0.05, 10000.0f);      // XXX: Look here near far information
00841 
00842    vprASSERT(masterChan != NULL);
00843 
00844    /*  Original code for reference
00845     * masterChan->setShare(PFCHAN_NEARFAR | PFCHAN_EARTHSKY |
00846     *                    PFCHAN_STRESS | PFCHAN_LOD | PFCHAN_SWAPBUFFERS |
00847     *                    PFCHAN_APPFUNC | PFCHAN_SCENE | PFCHAN_CULLFUNC | PFCHAN_STATS_DRAWMODE );
00848     */
00849 
00850    //
00851    // Set the Channel attribs based on cur settings
00852    //
00853    unsigned cur_share = masterChan->getShare();          // Get current setting, and OR the new stuff on
00854    unsigned turn_on = ( PFCHAN_NEARFAR | PFCHAN_EARTHSKY |
00855                         PFCHAN_STRESS | PFCHAN_LOD | PFCHAN_SWAPBUFFERS |
00856                         PFCHAN_APPFUNC | PFCHAN_SCENE | PFCHAN_CULLFUNC |
00857                         PFCHAN_STATS_DRAWMODE);
00858    unsigned turn_off = (   PFCHAN_FOV |
00859                            PFCHAN_VIEW |
00860                            PFCHAN_VIEW_OFFSETS |
00861                            PFCHAN_DRAWFUNC );
00862 
00863    masterChan->setShare((cur_share | turn_on) &(~turn_off));
00864 
00865    //masterChan->setTravFunc(PFTRAV_APP, PfAppFunc);
00866    //masterChan->setShare(PFCHAN_NEARFAR | PFCHAN_EARTHSKY |
00867    //                     PFCHAN_STRESS | PFCHAN_SWAPBUFFERS |
00868    //                     PFCHAN_APPFUNC | PFCHAN_CULLFUNC );
00869 }

void vrj::PfDrawManager::addDisplay ( Display disp  )  [virtual]

Callback when display is added to display manager.

Precondition:
Must be in kernel controlling thread. Must have already initialized Performer.

Implements vrj::DrawManager.

Definition at line 368 of file PfDrawManager.cpp.

References allocatePipeWin(), vrj::PfInputHandler::config(), vrj::DrawSimInterface::config(), debugDump(), vrj::PfDrawManager::pfDisplay::disp, vrj::Display::getConfigElement(), vrj::Viewport::getConfigElement(), vrj::Display::getGlFrameBufferConfig(), getMonoFBConfig(), vrj::Display::getName(), vrj::Display::getNumViewports(), vrj::Viewport::getOriginAndSize(), vrj::Display::getOriginAndSize(), getPfPipe(), vrj::Display::getPipe(), getStereoFBConfig(), vrj::Display::getViewport(), initChanGroupAttribs(), vrj::DrawSimInterface::initialize(), vrj::Viewport::isActive(), vrj::Viewport::isSimulator(), vrj::Display::isStereoRequested(), vrj::Viewport::isSurface(), mDisplays, mPfHasForked, mPfInputHandlers, mRoot, mRootWithSim, mSimChannels, mSimMasterChan, mSurfChannels, mSurfMasterChan, PFconfigPWin, vrj::PfDrawFuncMonoBackbuffer(), vrj::PfDrawFuncStereoLeft(), vrj::PfDrawFuncStereoRight(), vrj::PfDrawManager::pfViewport::PRIMARY, vrj::PfDrawManager::pfDisplay::pWin, vrj::PfDrawManager::pfViewport::SECONDARY, vrj::SimViewport::setDrawSimInterface(), vrj::Display::shouldDrawBorder(), vrj::Display::shouldHideMouse(), vrj::PfDrawManager::pfDisplay::viewports, and vrjDBG_DRAW_MGR().

00369 {
00370    vprASSERT(disp != NULL);    // Can't add a null display
00371    vprASSERT((true == mPfHasForked) && "Trying to add display when performer has not been initialized");
00372 
00373    //  For the display
00374    //     -Create a pWin for it
00375    //     - For each viewport
00376    //        - Create viewport
00377    //        - Create channels for the viewports
00378    vprDEBUG_OutputGuard(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL,
00379                         std::string("vrj::PfDrawManager: ---- Opening new Display --------\n"),
00380                         std::string("vrj::PfDrawManager: ---- Display Open (done) --------\n"));
00381 
00382 
00383 
00384    pfDisplay pf_disp;            // The pfDisplay to use
00385    pf_disp.disp = disp;
00386 
00387    vprDEBUG(vrjDBG_DRAW_MGR,vprDBG_CONFIG_LVL) << "\tDisplay is:" << (void*)(disp) << std::endl << vprDEBUG_FLUSH;
00388    vprDEBUG(vrjDBG_DRAW_MGR,vprDBG_CONFIG_LVL) << "\tPfDrawManager::add Display: Got Display:\n" << (*disp) << vprDEBUG_FLUSH;
00389 
00390    int xo, yo, xs, ys;
00391    pfPipe* pipe = getPfPipe(disp->getPipe());      // Get the pipe
00392 
00393    // Make sure we have a good pipe.  If not, there isn't anything we can do
00394    // to recover.
00395    if ( NULL == pipe )
00396    {
00397       vprASSERT(NULL != pipe);
00398       return;
00399    }
00400 
00401    // --- SETUP PWIN --- //
00402    pf_disp.pWin = allocatePipeWin(disp->getPipe());     //  new pfPipeWindow(pipe);
00403    vprASSERT(NULL != pf_disp.pWin);
00404 
00405    disp->getOriginAndSize(xo, yo, xs, ys);
00406    
00407    pf_disp.pWin->setOriginSize(xo, yo, xs, ys);
00408 
00409    // Setup window border
00410    if (disp->shouldDrawBorder())
00411       pf_disp.pWin->setName(disp->getName().c_str()); // Give the window a name
00412    else
00413       pf_disp.pWin->setMode(PFWIN_NOBORDER, 1);          // Get rid of that border
00414 
00415    jccl::ConfigElementPtr fb_elt = disp->getGlFrameBufferConfig();
00416    const int visual_id = fb_elt->getProperty<int>("visual_id");
00417 
00418    // If the user requested a specific visual ID, use it and ignore the rest
00419    // of the frame buffer configuration.
00420    if ( visual_id != -1 )
00421    {
00422       vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00423          << "Requesting visual 0x" << std::hex << visual_id << std::dec
00424          << "." << std::endl << vprDEBUG_FLUSH;
00425       pf_disp.pWin->setFBConfigId(visual_id);
00426    }
00427    else
00428    {
00429       // Setup Frame Buffer config
00430       if (disp->isStereoRequested())                     // If we need stereo
00431       {
00432          std::vector<int> fb_config = getStereoFBConfig(disp);
00433 
00434 #ifdef VJ_DEBUG
00435          // ouput debug info about the frame buffer config recieved
00436          vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_VERB_LVL)
00437             << "[vrj::PfDrawManager::addDisplay()] Got Stereo FB config\n"
00438             << vprDEBUG_FLUSH;
00439          for ( unsigned int i = 0; i < fb_config.size(); ++i )
00440          {
00441             vprDEBUG_CONT(vrjDBG_DRAW_MGR, vprDBG_VERB_LVL)
00442                << "  " << fb_config[i] << vprDEBUG_FLUSH;
00443          }
00444 #endif
00445 
00446          vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00447             << "[vrj::PfDrawManager::addDisplay()] "
00448             << "Configuring stereo window attribs.\n" << vprDEBUG_FLUSH;
00449          pf_disp.pWin->setFBConfigAttrs(&(fb_config[0]));     // Configure framebuffer for stereo
00450       }
00451       else
00452       {
00453          // Get frame buffer config
00454          std::vector<int> fb_config = getMonoFBConfig(disp);
00455 
00456 #ifdef VJ_DEBUG
00457          // ouput debug info about the frame buffer config recieved
00458          vprDEBUG(vrjDBG_DRAW_MGR,vprDBG_VERB_LVL)
00459             << "[vrj::PfDrawManager::addDisplay()] Got Mono FB config\n"
00460             << vprDEBUG_FLUSH;
00461          for ( unsigned int j = 0 ; j < fb_config.size(); ++j )
00462          {
00463             vprDEBUG_CONT(vrjDBG_DRAW_MGR,vprDBG_VERB_LVL)
00464                << "  " << fb_config[j] << std::endl << vprDEBUG_FLUSH;
00465          }
00466          vprDEBUG_CONT(vrjDBG_DRAW_MGR,vprDBG_VERB_LVL)
00467             << std::endl << vprDEBUG_FLUSH;
00468 #endif
00469 
00470          vprDEBUG(vrjDBG_DRAW_MGR,vprDBG_CONFIG_LVL)
00471             << "[vrj::PfDrawManager::addDisplay()] "
00472             << "Configuring mono window attribs.\n" << vprDEBUG_FLUSH;
00473          pf_disp.pWin->setFBConfigAttrs(&(fb_config[0]));       // Configure a "norm" window
00474       }
00475    }
00476 
00477    // -- Set config info -- //
00478    pf_disp.pWin->setConfigFunc(PFconfigPWin);   // Set config function
00479    pf_disp.pWin->config();                      // Next pfFrame, config Func will be called
00480 
00481    // --- SETUP VIEWPORTS --- //
00482    // for(each viewport)
00483    //   - Allocate channels
00484    //   - Set draw functions
00485    //   - Setup master chans
00486    Viewport* viewport = NULL;
00487    unsigned num_vps = disp->getNumViewports();
00488 
00489    vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) << "   Num viewports: " << num_vps << std::endl << vprDEBUG_FLUSH;
00490    for(unsigned vp_num=0; vp_num < num_vps; vp_num++)
00491    {
00492       viewport = disp->getViewport(vp_num);
00493 
00494       if(viewport->isActive())      // is viewport active
00495       {
00496          //Viewport::View view = viewport->getView();
00497          pfViewport pf_viewport;                         // The viewport to build up
00498          pf_viewport.viewport = viewport;
00499          float vp_ox, vp_oy, vp_sx, vp_sy;
00500 
00501          // Get channel info
00502          // Primary channel - (Left in stereo)
00503          viewport->getOriginAndSize(vp_ox, vp_oy, vp_sx, vp_sy);
00504          pf_viewport.chans[pfViewport::PRIMARY] = new pfChannel(pipe);
00505          pf_viewport.chans[pfViewport::PRIMARY]->setViewport(vp_ox, vp_ox+vp_sx, vp_oy, vp_oy+vp_sy);
00506          pf_disp.pWin->addChan(pf_viewport.chans[pfViewport::PRIMARY]);
00507 
00508          // Secondary channel - (Right in stereo)
00509          if(disp->isStereoRequested())
00510          {
00511             pf_viewport.chans[pfViewport::SECONDARY] = new pfChannel(pipe);
00512             pf_viewport.chans[pfViewport::SECONDARY]->setViewport(vp_ox, vp_ox+vp_sx, vp_oy, vp_oy+vp_sy);
00513             pf_disp.pWin->addChan(pf_viewport.chans[pfViewport::SECONDARY]);
00514          }
00515 
00516          // Set draw function
00517          if(disp->isStereoRequested())
00518          {
00519             pf_viewport.chans[pfViewport::PRIMARY]->setTravFunc(PFTRAV_DRAW, PfDrawFuncStereoLeft);
00520             pf_viewport.chans[pfViewport::SECONDARY]->setTravFunc(PFTRAV_DRAW, PfDrawFuncStereoRight);
00521          }
00522          else
00523          {
00524             pf_viewport.chans[pfViewport::PRIMARY]->setTravFunc(PFTRAV_DRAW, PfDrawFuncMonoBackbuffer);
00525          }
00526 
00527          // if surface ==> Setup surface channels
00528          if (viewport->isSurface())
00529          {
00530             vprASSERT(pf_viewport.chans[pfViewport::PRIMARY] != NULL);
00531 
00532             // Primary
00533             if(NULL == mSurfMasterChan)      // If NULL, then add us as the new one
00534             {
00535                mSurfMasterChan = pf_viewport.chans[pfViewport::PRIMARY];
00536                mSurfMasterChan->setScene(mRoot);
00537                initChanGroupAttribs(mSurfMasterChan);
00538                mSurfChannels.push_back(mSurfMasterChan);
00539             }
00540             else
00541             {
00542                mSurfChannels.push_back(pf_viewport.chans[pfViewport::PRIMARY]);
00543                mSurfMasterChan->attach(pf_viewport.chans[pfViewport::PRIMARY]);
00544             }
00545 
00546             // Secondary
00547             if(NULL != pf_viewport.chans[pfViewport::SECONDARY])
00548             {
00549                mSurfChannels.push_back(pf_viewport.chans[pfViewport::SECONDARY]);
00550                mSurfMasterChan->attach(pf_viewport.chans[pfViewport::SECONDARY]);
00551             }
00552 
00553          }
00554          // if sim ==> setup sim channels
00555          else if(viewport->isSimulator())
00556          {
00557             // -- Finish Simulator setup
00558             jccl::ConfigElementPtr vp_element = viewport->getConfigElement();
00559 
00560             SimViewport* sim_vp(NULL);
00561             sim_vp = dynamic_cast<SimViewport*>(viewport);
00562             vprASSERT(NULL != sim_vp);
00563 
00564             sim_vp->setDrawSimInterface(NULL);
00565 
00566             // Create the simulator stuff
00567             vprASSERT(1 == vp_element->getNum("simulator_plugin") && "You must supply a simulator plugin.");
00568 
00569             jccl::ConfigElementPtr sim_element =
00570                vp_element->getProperty<jccl::ConfigElementPtr>("simulator_plugin");
00571 
00572             vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00573                << "PfDrawManager::addDisplay() creating simulator of type '"
00574                << sim_element->getID() << "'\n" << vprDEBUG_FLUSH;
00575 
00576             DrawSimInterface* new_sim_i =
00577                PfSimInterfaceFactory::instance()->createObject(sim_element->getID());
00578 
00579             // XXX: Change this to an error once the new simulator loading code is
00580             // more robust.  -PH (4/13/2003)
00581             vprASSERT(NULL != new_sim_i && "Failed to create draw simulator");
00582             sim_vp->setDrawSimInterface(new_sim_i);
00583             new_sim_i->initialize(sim_vp);
00584             new_sim_i->config(sim_element);
00585 
00586 
00587             vprASSERT(pf_viewport.chans[pfViewport::PRIMARY] != NULL);
00588 
00589             // Primary
00590             if(NULL == mSimMasterChan)        // If NULL, then make us the master
00591             {
00592                mSimMasterChan = pf_viewport.chans[pfViewport::PRIMARY];
00593                mSimMasterChan->setScene(mRootWithSim);       // Set the shared "normal" scene
00594                initChanGroupAttribs(mSimMasterChan);       // Setup the channel group attribs
00595                mSimChannels.push_back(mSimMasterChan);
00596             }
00597             else
00598             {
00599                mSimChannels.push_back(pf_viewport.chans[pfViewport::PRIMARY]);
00600                mSimMasterChan->attach(pf_viewport.chans[pfViewport::PRIMARY]);
00601             }
00602 
00603             // Secondary
00604             if(NULL != pf_viewport.chans[pfViewport::SECONDARY])
00605             {
00606                mSimChannels.push_back(pf_viewport.chans[pfViewport::SECONDARY]);
00607                mSimMasterChan->attach(pf_viewport.chans[pfViewport::SECONDARY]);
00608             }
00609          }
00610 
00611          // Add viewport to the display list
00612          pf_disp.viewports.push_back(pf_viewport);
00613 
00614       }  // is viewport active
00615    }     // for each viewport
00616 
00617    // -- Add new pfDisp to disp Vector -- //
00618    mDisplays.push_back(pf_disp);
00619 
00620    // Call pfFrame to cause the pipeWindow configured to be opened and setup.
00621    pfFrame();
00622    
00623    // This is neccessary because it may take a couple
00624    // frames for the window to fully open. This information was
00625    // found in "man pfPipeWindow".
00626 
00627    // Performer says that if you trigger a window from the applciation proccess
00628    // you must wait for the window to open during the draw process.
00629    while( !pfIsPWinOpen( pf_disp.pWin ) )
00630    {
00631       pfFrame();
00632       vpr::System::usleep( 500 ); 
00633    }
00634 
00635    PfInputHandler* new_input_handler = new PfInputHandler(pf_disp.pWin, disp->getName());
00636    
00637    // Configure the Performer window to accept events.
00638    jccl::ConfigElementPtr display_elt = disp->getConfigElement();
00639    new_input_handler->config(display_elt, disp);
00640 
00641    
00642    mPfInputHandlers.push_back(new_input_handler);
00643 
00644    if(pf_disp.disp->shouldHideMouse())
00645    {
00646       pfuLoadPWinCursor(pf_disp.pWin, PFU_CURSOR_OFF);
00647    }
00648    
00649    // Dump the state
00650    vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00651       << "Reconfiged the pfDrawManager.\n" << vprDEBUG_FLUSH;
00652    //vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) << (*this) << vprDEBUG_FLUSH;
00653    debugDump(vprDBG_CONFIG_LVL);
00654 }

void vrj::PfDrawManager::removeDisplay ( Display disp  )  [virtual]

Callback when display is removed to display manager.

Precondition:
disp must be a valid display that we have.
Postcondition:
Window for disp is removed from the draw manager and child pipes.

Implements vrj::DrawManager.

Definition at line 689 of file PfDrawManager.cpp.

References mDisplays, releaseDisplay(), and vrjDBG_DRAW_MGR().

00690 {
00691    // Find the pfDisplay
00692 #ifdef VPR_OS_Windows
00693    // Visual C++ does not have std::compose1(), so we have to do this the
00694    // tedious, non-template-coolness way.
00695    std::vector<pfDisplay>::iterator disp_i;
00696    for ( disp_i = mDisplays.begin(); disp_i != mDisplays.end(); ++disp_i )
00697    {
00698       if ( disp == (*disp_i).disp )
00699       {
00700          break;
00701       }
00702    }
00703 #else
00704    std::vector<pfDisplay>::iterator disp_i = std::find_if(mDisplays.begin(), mDisplays.end(),
00705                          std::compose1( std::bind2nd( std::equal_to<Display*>(),disp),
00706                                         pfDisplay_disp()) );
00707 #endif
00708 
00709 
00710    if(mDisplays.end() == disp_i)
00711    {
00712       vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) << "ERROR: PfDrawManager::removeDisplay: Tried to remove a non-existant display\n" << vprDEBUG_FLUSH;
00713       return;
00714    }
00715 
00716 
00717    // Release the pfDisplay
00718    releaseDisplay(*disp_i);
00719 
00720    // Remove display from the list
00721    mDisplays.erase(disp_i);
00722 }

void vrj::PfDrawManager::closeAPI (  )  [virtual]

Shuts down the drawing API.

Implements vrj::DrawManager.

Definition at line 1169 of file PfDrawManager.cpp.

01170 {
01171    // NOTE: We do not call pfExit() here because it would cause the whole
01172    // process to exit.  If users want to call pfExit(), they must do so on
01173    // their own at whatever time is appropriate for their application.
01174    pfuExitUtil();
01175 }

void vrj::PfDrawManager::updatePfProjections (  )  [virtual]

Updates all the projections for the displays.

Postcondition:
All windows have the projections correctly set.

Definition at line 1177 of file PfDrawManager.cpp.

References vrj::App::getDrawScaleFactor(), vrj::Viewport::getLeftProj(), vrj::Viewport::getRightProj(), vrj::Viewport::getView(), vrj::Viewport::isSimulator(), vrj::Viewport::LEFT_EYE, mApp, vrj::DrawManager::mDisplayManager, mDisplays, vrj::PfDrawManager::pfViewport::PRIMARY, vrj::Viewport::RIGHT_EYE, vrj::PfDrawManager::pfViewport::SECONDARY, vrj::Viewport::STEREO, updatePfProjection(), vrj::DisplayManager::updateProjections(), vrj::PfSimInterface::updateSimulatorSceneGraph(), and vrjDBG_DRAW_MGR().

Referenced by draw().

01178 {
01179    vprDEBUG(vrjDBG_DRAW_MGR,vprDBG_VERB_LVL)
01180       << "[vrj::PfDrawManager::updatePfProjections()] Entering." << std::endl
01181       << vprDEBUG_FLUSH;
01182 
01183    // Update display projections
01184    float scale_factor = mApp->getDrawScaleFactor();
01185    mDisplayManager->updateProjections(scale_factor);
01186 
01187    // --- Update the channel projections --- //
01188    //for(each pfDisp)
01189    //   for(each viewport)
01190    //       update Performer specific stuff.
01191    for (unsigned disp_id=0;disp_id<mDisplays.size();disp_id++)    // each display
01192    {
01193       pfDisplay* cur_disp = &(mDisplays[disp_id]);
01194 
01195       vprASSERT(cur_disp->disp != NULL);
01196       for(unsigned vp=0;vp<cur_disp->viewports.size();vp++)       // each viewport
01197       {
01198          pfViewport* pf_vp = &(cur_disp->viewports[vp]);
01199          vprASSERT(pf_vp != NULL);
01200          vprASSERT(pf_vp->viewport != NULL);
01201 
01202          /*
01203          SurfaceViewport* surf_vp(NULL);
01204          */
01205 
01206          Viewport* cur_vp(pf_vp->viewport);
01207          Viewport::View view;
01208 
01209          // --- All viewports --- //
01210          //surf_vp = dynamic_cast<SurfaceViewport*>(pf_vp->viewport);
01211          //vprASSERT(surf_vp != NULL && "Could not cast supposedly surface display to SurfaceDisplay.");
01212          view = cur_vp->getView();
01213 
01214          if(Viewport::LEFT_EYE == view)
01215          {
01216             updatePfProjection(pf_vp->chans[pfViewport::PRIMARY], cur_vp->getLeftProj());
01217          }
01218          else if(Viewport::RIGHT_EYE == view)
01219          {
01220             updatePfProjection(pf_vp->chans[pfViewport::PRIMARY], cur_vp->getRightProj());
01221          }
01222          else if(Viewport::STEREO == view)
01223          {
01224             updatePfProjection(pf_vp->chans[pfViewport::PRIMARY], cur_vp->getLeftProj());
01225             updatePfProjection(pf_vp->chans[pfViewport::SECONDARY], cur_vp->getRightProj());
01226          }
01227          else
01228          {
01229             vprASSERT(false && "[vrj::PfDrawManager::updateProjections()] We don't have a valid display type, don't know what to do");
01230          }
01231 
01232          // Sim viewport
01233          if(cur_vp->isSimulator())
01234          {
01235             SimViewport*      sim_vp(NULL);
01236             PfSimInterface*   draw_sim_i(NULL);
01237 
01238             sim_vp = dynamic_cast<SimViewport*>(pf_vp->viewport);
01239             vprASSERT(sim_vp != NULL && "Could not cast supposed simulator display to SimDisplay.");
01240 
01241             draw_sim_i = dynamic_cast<PfSimInterface*>(sim_vp->getDrawSimInterface());
01242             vprASSERT(draw_sim_i != NULL && "Could not cast supposed simulator interface to PfSimInterface.");
01243 
01244             draw_sim_i->updateSimulatorSceneGraph();
01245          }
01246 
01247       }
01248    }
01249 }

void vrj::PfDrawManager::debugDump ( int  debugLevel  ) 

Helper function that finds the pfDisp given a channel.

This function just loops through all the entries in the disps variable, looking for one that contains the channel. When it is found, it is returned.

Note:
The "cool" STL functor search didn't work for some reason.

Definition at line 1345 of file PfDrawManager.cpp.

References debugDumpPfDisp(), mApp, mDisplays, mRoot, mRootWithSim, and vrjDBG_DRAW_MGR().

Referenced by addDisplay().

01346 {
01347    vprDEBUG_BEGIN(vrjDBG_DRAW_MGR,debugLevel)
01348       << "-- DEBUG DUMP --------- "
01349       << clrOutNORM(clrCYAN,"vrj::PfDrawManager: 0x")
01350       << std::hex << (void*)this << " ------------" << std::dec << std::endl
01351       << vprDEBUG_FLUSH;
01352    vprDEBUG_NEXT(vrjDBG_DRAW_MGR,debugLevel)
01353       << "App: 0x" << std::hex << (void*)mApp << std::dec << std::endl
01354       << vprDEBUG_FLUSH;
01355    vprDEBUG_NEXT(vrjDBG_DRAW_MGR,debugLevel)
01356       << "Scene: 0x" << std::hex << (void*)mRoot << std::dec << std::endl
01357       << vprDEBUG_FLUSH;
01358    vprDEBUG_NEXT(vrjDBG_DRAW_MGR,debugLevel)
01359       << "Sim scene: 0x" << std::hex << (void*)mRootWithSim << std::dec
01360       << std::endl << vprDEBUG_FLUSH;
01361    vprDEBUG_NEXT(vrjDBG_DRAW_MGR,debugLevel)
01362       << "Number of displays: " << mDisplays.size() << std::endl
01363       << vprDEBUG_FLUSH;
01364 
01365    for (std::vector<pfDisplay>::iterator i = mDisplays.begin(); i != mDisplays.end(); i++)
01366    {
01367       debugDumpPfDisp(&(*i),debugLevel);
01368    }
01369 
01370    vprDEBUG_END(vrjDBG_DRAW_MGR,debugLevel) << "-------- Dump end ----\n" << vprDEBUG_FLUSH;
01371 }

void vrj::PfDrawManager::debugDumpPfDisp ( pfDisplay pf_disp,
int  debugLevel 
)

Definition at line 1374 of file PfDrawManager.cpp.

References vrj::PfDrawManager::pfDisplay::disp, vrj::PfDrawManager::pfDisplay::pWin, vrj::PfDrawManager::pfDisplay::viewports, and vrjDBG_DRAW_MGR().

Referenced by debugDump().

01375 {
01376    vprDEBUG_BEGIN(vrjDBG_DRAW_MGR,debugLevel)
01377       << "Display: " << (void*)(pf_disp->disp) << std::endl << vprDEBUG_FLUSH;
01378    vprDEBUG_NEXT(vrjDBG_DRAW_MGR,debugLevel)
01379       << "pWin: " << (void*)(pf_disp->pWin) << std::endl << vprDEBUG_FLUSH;
01380    vprDEBUG_NEXT(vrjDBG_DRAW_MGR,debugLevel)
01381       << "visual ID: 0x" << std::hex << pf_disp->pWin->getFBConfigId()
01382       << std::dec << std::endl << vprDEBUG_FLUSH;
01383 
01384    for(unsigned vp=0; vp<pf_disp->viewports.size(); ++vp)
01385    {
01386       vprASSERT((pf_disp->viewports[vp].viewport != NULL) && "NULL viewport in pf_disp. Check if it was ever set.");
01387 
01388       vprDEBUG_NEXT(vrjDBG_DRAW_MGR,debugLevel) << "Viewport: " << vp << vprDEBUG_FLUSH;
01389       vprDEBUG_NEXT(vrjDBG_DRAW_MGR,debugLevel) << "      vp: " << *(pf_disp->viewports[vp].viewport) << vprDEBUG_FLUSH;
01390 
01391       for(int ch=0;ch<2;ch++)
01392       {
01393          pfChannel* cur_chan = pf_disp->viewports[vp].chans[ch];
01394          unsigned chan_mask(0);
01395          if(cur_chan != NULL)
01396             chan_mask = cur_chan->getShare();
01397          vprDEBUG_NEXT(vrjDBG_DRAW_MGR,debugLevel)
01398               << "chan:" << ch << " -- " << (void*)cur_chan
01399               << "  shared: FOV:" << (chan_mask & PFCHAN_FOV)
01400               << " Scene:" << (chan_mask & PFCHAN_SCENE)
01401               << " AppFunc:" << (chan_mask & PFCHAN_APPFUNC)
01402               << " SwapBuff:" << (chan_mask & PFCHAN_SWAPBUFFERS)
01403               << " SwapBuff-HW:" << (chan_mask & PFCHAN_SWAPBUFFERS_HW)
01404               << std::endl << vprDEBUG_FLUSH;
01405       }
01406    }
01407 
01408    vprDEBUG_CONT_END(vrjDBG_DRAW_MGR,debugLevel) << vprDEBUG_FLUSH;
01409 }

virtual bool vrj::PfDrawManager::configCanHandle ( jccl::ConfigElementPtr  element  )  [inline, virtual]

Can the handler handle the given element?

Returns:
true if we can handle it; false otherwise.

Definition at line 211 of file PfDrawManager.h.

00212    {
00213       boost::ignore_unused_variable_warning(element);
00214       return false;
00215    }

virtual bool vrj::PfDrawManager::configAdd ( jccl::ConfigElementPtr  element  )  [inline, protected, virtual]

Adds the element to the configuration.

Precondition:
configCanHandle(element) == true.
Returns:
false.

Definition at line 223 of file PfDrawManager.h.

00224    {
00225       boost::ignore_unused_variable_warning(element);
00226       vprDEBUG(vprDBG_ALL,vprDBG_CRITICAL_LVL)
00227          << "vrj::PfDrawManager::configAdd: configAdd is not supported.\n"
00228          << vprDEBUG_FLUSH;
00229       return false;
00230    }

virtual bool vrj::PfDrawManager::configRemove ( jccl::ConfigElementPtr  element  )  [inline, protected, virtual]

Removes the element from the current configuration.

Precondition:
configCanHandle(element) == true.
Returns:
false.

Definition at line 237 of file PfDrawManager.h.

00238    {
00239       boost::ignore_unused_variable_warning(element);
00240       vprDEBUG(vprDBG_ALL,vprDBG_CRITICAL_LVL)
00241          << "vrj::PfDrawManager::configRemove: configRemove is not supported.\n"
00242          << vprDEBUG_FLUSH;
00243       return false;
00244    }

bool vrj::PfDrawManager::configDisplaySystem ( jccl::ConfigElementPtr  element  )  [protected]

Sets up display system related attributes.

Precondition:
element is a config element of the "dispaySystem" type.
Note:
MUST be called before initDrawing.

This must be called by the draw manager because the element must be gotten from the draw manager.

Definition at line 107 of file PfDrawManager.cpp.

References mNumPipes, mPipeStrs, and vrjDBG_DRAW_MGR().

Referenced by initAPI().

00108 {
00109    vprASSERT(element.get() != NULL);
00110    vprASSERT(element->getID() == std::string("display_system"));
00111 
00112    // ---- SETUP PipeStr's ---- //
00113    vprDEBUG_BEGIN(vrjDBG_DRAW_MGR,vprDBG_CONFIG_LVL)
00114       << "------------- PfDrawManager::config ----------------" << std::endl
00115       << vprDEBUG_FLUSH;
00116    mNumPipes = element->getProperty<unsigned int>("number_of_pipes");
00117 
00118    vprDEBUG(vrjDBG_DRAW_MGR,vprDBG_CONFIG_LVL) << "NumPipes: " << mNumPipes
00119                                             << std::endl << vprDEBUG_FLUSH;
00120 
00121    // Make sure that the user has specified a valid number of pipes in the
00122    // configuration. This becomes an issue normally since the default number of
00123    // pipes when creating a new display_system element is 0. It needs to be this
00124    // because we can not fill in the list of pipes with default values.
00125    if(mNumPipes < 1)
00126    {
00127       mNumPipes = 1;
00128    }
00129 
00130    for (unsigned int i=0;i<mNumPipes;i++)
00131    {
00132       std::string cur_disp_name = "-1";
00133 
00134       // NOTE: ConfigElements return the default value for a property if a value is
00135       //       not present. So if a pipe string is not specified for this pipe then
00136       //       it gets the default value of "-1".
00137       mPipeStrs.push_back(element->getProperty<std::string>("x11_pipes", i));
00138 
00139       if(mPipeStrs[i] == cur_disp_name)    // Use display env
00140       {
00141          std::string display_env;
00142          vpr::System::getenv("DISPLAY", display_env);
00143 
00144          if ( ! display_env.empty() )
00145          {
00146             mPipeStrs[i] = display_env;
00147          }
00148       }
00149       vprDEBUG(vrjDBG_DRAW_MGR,vprDBG_CONFIG_LVL) << "Pipe:" << i << ": "
00150                                                << mPipeStrs[i] << std::endl
00151                                                << vprDEBUG_FLUSH;
00152    }
00153    return true;
00154 }

void vrj::PfDrawManager::callAppChanFuncs (  )  [protected]

Calls all the application channel callbacks.

Definition at line 189 of file PfDrawManager.cpp.

References vrj::PfApp::appChanFunc(), mApp, and mDisplays.

Referenced by draw().

00190 {
00191    // for(each display)
00192    //    for(each viewport)
00193    //       for(each channel)
00194    for(unsigned int dispIndex=0;dispIndex<mDisplays.size();dispIndex++)
00195    {
00196       for(unsigned vp=0;vp<mDisplays[dispIndex].viewports.size();vp++)
00197       {
00198          for(unsigned ch=0;ch<2;ch++)
00199          {
00200             if(mDisplays[dispIndex].viewports[vp].chans[ch] != NULL)
00201                mApp->appChanFunc(mDisplays[dispIndex].viewports[vp].chans[ch]);
00202          }
00203       }
00204    }
00205 }

void vrj::PfDrawManager::updatePfProjection ( pfChannel *  chan,
Projection proj 
) [protected]

Postcondition:
chan has its view matrix set to the Performer.

Equivalent of proj's projection data.

Definition at line 1255 of file