Re: pfApp traversal called multiple times in channel group

New Message Reply Date view Thread view Subject view Author view

From: Allen Bierbaum (allenb++at++vrac.iastate.edu)
Date: 06/28/2000 07:41:53


I still have not found the cause of this problem (bug???).

I have modified the multiwin.C example program included with Iris
Performer so that it puts all the channels in a single channel group.
Once a put a PFAPP_TRAV callback on the channels and/or nodes in the
graph, the callbacks get called once per channel even though the channel
group's attribs specify that it should not.

Any ideas?

-Allen

Here is the code:
---------------------------------------
// multiwinC.C: Performer program to demonstrate multiple windows
// in one pipe. Derived from simple.c
//
// $Revision: 1.10 $
// $Date: 1995/11/22 14:35:15 $
//
//
#include <stdlib.h>
#include <iostream.h>
#include <Performer/pf/pfChannel.h>
#include <Performer/pf/pfScene.h>
#include <Performer/pf/pfLightSource.h>
#include <Performer/pr/pfLight.h>
#include <Performer/pf/pfTraverser.h>
#include <Performer/pfdu.h>

static void OpenPipeWin(pfPipeWindow *pw);
void chanAppTravFunc(pfChannel *chan, void* chandata);
int nodeTravAppPre(pfTraverser* trav, void* userData);
int nodeTravAppPost(pfTraverser* trav, void* userData);

//
// Usage() -- print usage advice and exit. This
// procedure is executed in the application process.
//
static void
Usage (void)
{
    pfNotify(PFNFY_FATAL, PFNFY_USAGE, "Usage: multiwinC file.ext
...\n");
    exit(1);
}

int
main (int argc, char *argv[])
{
   float t = 0.0f;
   pfPipeWindow *pwin[16];
   pfChannel *chan[16];
   int loop;
   int NumWins = 4;
   char str[PF_MAXSTRING];

   if (argc < 2)
      Usage();

   // Initialize Performer
   pfInit();

   // Use default multiprocessing mode based on number of
   // processors.
   //
   pfMultiprocess( PFMP_DEFAULT );

   // Load all loader DSO's before pfConfig() forks
   pfdInitConverter(argv[1]);

   // Configure multiprocessing mode and start parallel
   // processes.
   //
   pfConfig();

   // Append to PFPATH additional standard directories where
   // geometry and textures exist
   //
   pfFilePath(".:/usr/share/Performer/data");

   // Read a single file, of any known type.
   pfNode *root = pfdLoadFile(argv[1]);
   if (root == NULL)
   {
      pfExit();
      exit(-1);
   }

   // Attach loaded file to a pfScene.
   pfScene *scene = new pfScene;
   scene->addChild(root);
   root->setName("Root");
   root->setTravFuncs(PFTRAV_APP,nodeTravAppPre,nodeTravAppPost);

   // determine extent of scene's geometry
   pfSphere bsphere;
   scene->getBound(&bsphere);

   // Create a pfLightSource and attach it to scene.
   scene->addChild(new pfLightSource);

   // Configure and open GL window
   pfPipe *p = pfGetPipe(0);
   for (loop=0; loop < NumWins; loop++)
   {
      pwin[loop] = new pfPipeWindow(p);
      sprintf(str, "IRIS Performer - Win %d", loop);
      pwin[loop]->setName(str);
      pwin[loop]->setOriginSize((loop&0x1)*315, ((loop&0x2)>>1)*340,
                                300, 300);
      pwin[loop]->setConfigFunc(OpenPipeWin);
      pwin[loop]->config();
   }

   // Create and configure a pfChannel.
   for (loop=0; loop < NumWins; loop++)
   {
      chan[loop] = new pfChannel(p);
      pwin[loop]->addChan(chan[loop]);
      chan[loop]->setScene(scene);
      chan[loop]->setNearFar(1.0f, 10.0f * bsphere.radius);
      chan[loop]->setFOV(45.0f, 0.0f);
   }

   // Configure channel group
   pfChannel* master_chan = chan[0];

   master_chan->setShare(PFCHAN_NEARFAR | PFCHAN_EARTHSKY |
                   PFCHAN_STRESS | PFCHAN_LOD | PFCHAN_SWAPBUFFERS |
                   PFCHAN_APPFUNC | PFCHAN_CULLFUNC |
PFCHAN_STATS_DRAWMODE );

   master_chan->setTravFunc(PFTRAV_APP, chanAppTravFunc);

   for (loop=1;loop<NumWins;loop++)
   {
      master_chan->attach(chan[loop]);
   }

   // Doesn't work this way either
   /*
   master_chan->setShare(PFCHAN_NEARFAR | PFCHAN_EARTHSKY |
                         PFCHAN_STRESS | PFCHAN_LOD | PFCHAN_SWAPBUFFERS
|
                         PFCHAN_APPFUNC | PFCHAN_CULLFUNC |
PFCHAN_STATS_DRAWMODE );
   master_chan->setTravFunc(PFTRAV_APP, chanAppTravFunc);
   */

   // Simulate for twenty seconds.
   while (t < 20.0f)
   {
      float s, c;
      pfCoord view;

      // Go to sleep until next frame time.
      pfSync();

      cout << "------------- << Synced >> --------------" << endl;

      // Compute new view position.
      t = pfGetTime();
      pfSinCos(45.0f*t, &s, &c);
      view.hpr.set(45.0f*t, -10.0f, 0);
      view.xyz.set(2.0f * bsphere.radius * s,
                   -2.0f * bsphere.radius *c,
                   0.5f * bsphere.radius);

      for (loop=0; loop < NumWins; loop++)
         chan[loop]->setView(view.xyz, view.hpr);

      // Initiate cull/draw for this frame.
      pfFrame();
   }

   // Terminate parallel processes and exit.
   pfExit();

   return 0;
}

//
// OpenPipeWin() -- create a GL window: set up the
// window system, IRIS GL, and IRIS Performer. This
// procedure is executed for each window in the draw process
// for that pfPipe.
//
static void
OpenPipeWin(pfPipeWindow *pw)
{
    pfPipe *p = pw->getPipe();

    // share GL objects with all the windows on the pipe
    pw->open();

    // create a light source in the "south-west" (QIII)
    pfLight *Sun = new pfLight;
    Sun->setPos(-0.3f, -0.3f, 1.0f, 0.0f);
}

void chanAppTravFunc(pfChannel *chan, void* chandata)
{
   cout << "App traversal chan: " << chan << endl;
   pfApp();
}

int nodeTravAppPre(pfTraverser* trav, void* userData)
{
   cout << "App node pre-trav: node:" << (void*)trav->getNode() << "
named:" << trav->getNode()->getName() << endl << flush;
   return PFTRAV_CONT;
}

int nodeTravAppPost(pfTraverser* trav, void* userData)
{
   cout << "App node post-trav: node:" << (void*)trav->getNode() << "
named:" << trav->getNode()->getName() << endl << flush;
   return PFTRAV_CONT;
}

-----------------------------------------

Allen Bierbaum wrote:
>
> Hello all,
>
> I am facing the following strange problem.
>
> I have create a channel group of several channels. I set the shared
> channel attributes up with the following attribs:
>
> masterChan->setShare(PFCHAN_NEARFAR | PFCHAN_EARTHSKY |
> PFCHAN_STRESS | PFCHAN_SWAPBUFFERS |
> PFCHAN_APPFUNC | PFCHAN_CULLFUNC );
>
> After I do this, I check all the channels in the group, and they do have
> these parameters set.
>
> My problem is that even though I am sharing the app func
> (PFCHAN_APPFUNC), my application callback and node app callback
> functions are being called once for ever single pfChannel in the channel
> group.
>
> For example:
>
> If I do the following:
> masterChan->setTravFunc(PFTRAV_APP, testAppFunc);
>
> The function gets shared across all channels, but every channel calls
> the function. Not just the master as I would have expected.
>
> >From the Performer man pages, this seems to be an incorrect behavior.
> The man pages say:
>
> ...
> PFCHAN_APPFUNC
> The application callback is invoked once for all channels
> sharing PFCHAN_APPFUNC.
> ...
> pfApp carries out the application traversal for the channel and should
> only be invoked in the application callback specified by
> pfChanTravFunc.
> The application callback is invoked once for each channel group
> that is
> sharing PFCHAN_APPFUNC.
> ....
>
> Am I missing something here? Is Performer behaving badly, or is the man
> page incorrect?
>
> -Alle
>
> --
>
> Allen Bierbaum
> ISU SE Lab
> Research Assistant
> -----------------------------------------------------------------------
> List Archives, FAQ, FTP: http://www.sgi.com/software/performer/
> Submissions: info-performer++at++sgi.com
> Admin. requests: info-performer-request++at++sgi.com

-- 

Allen Bierbaum ISU -- Virtual Reality Applications Lab Research Assistant


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Wed Jun 28 2000 - 07:43:32 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.