next up previous
Next: Performer (C++ API) Up: Programmieren mit der CAVELib Previous: OpenGL

Unterabschnitte
  • Laden einer Geometrie

    Performer (C API)

    Aufbau eines Performer/CAVELib-Programmes

    1.
    pfInit() Initialisiert den Performer. Sollte ganz am Beginn eines Performer-Programmes stehen.

    2.
    pfCAVEConfig(&argc, argv, NULL) Die Konfigurationsfunktion fuer die CAVELib, muß nach pfInit und vor pfConfig aufgerufen werden.

    3.
    pfConfig() Konfiguriert den Performer (Pipelines, Multiprocessing Modes) entsprechend den Daten, die von pfCAVEConfig gefunden wurden. pfConfig sollte nur einmal zwischen pfInit und pfExit aufgerufen werden, am besten nach pfCAVEConfig

    4.
    pfCAVEInitChannels() Ersetzt alle Performerkommandos, die fuer das Initialisieren von den Channels und den Windows zuständig sind. Muß nach pfConfig aufgerufen werden.

    5.
    Erzeugen eines Performer-Szenengraphen.

    6.
    pfCAVEMasterChan() liefert einen Zeiger auf den MasterChannel der CAVELib-Channelgroup zurück, an diesen Channel muss die anzuzeigende Szene gehängt werden. (pfChanScene(pfCAVEMasterChan(), scene)) Kann erst aufgerufen werden, nachdem mit pfCAVEInitChannels die Channels initialisiert worden sind.

    7.
    Start der Simulationsschleife.

    8.
    Update des Szenengraphen.

    9.
    pfCAVEPreFrame() Liest die Trackerdaten aus und berechnet daraus die neuen Frusta für jede CAVE-Wand. Sollte einmal vor pfFrame aufgerufen werden.

    10.
    pfFrame erzeugt den nächsten Frame.

    11.
    pfCAVEPostFrame() Sollte einmal nach pfFrame aufgerufen werden.

    12.
    Ende der Simulationsschleife.

    13.
    pfCAVEHalt() gibt alle Resourcen der CAVELib frei, sollte noch vor pfExit aufgerufen werden.

    14.
    pfExit() schließt alle Graphik-Fenster, gibt alle Performer-Resourcen frei und beendet alle noch laufenden Performerprozesse. Sollte jedes Performer-Programm abschliessen.

    Beispielprogramm

    Ein kurzes Programm, das einen sich drehenden Wuerfel in die Mitte des CAVEs zeichnet.

    cube.c

    /* includes*/
    #include <stdlib.h>
    #include <math.h>
    #include <Performer/pf.h>
    #include <Performer/pfdu.h>
    #include <Performer/pfutil.h>
    
    #include <cave_ogl.h>
    #include <pfcave.h>
    
    /* main */
    int main(int argc, char **argv) {
    
      pfScene	*scene;
      pfDCS		*dcs;
      pfGeode	*geode;
      pfGeoSet	*gs;
      pfChannel	*chan;
      char	name[80];
    
      /* initialise the Performer */
      pfInit();
    
      /* configure the CAVELib */
      pfCAVEConfig(&argc, argv, NULL);	
    
      /* configure the Performer */
      pfConfig();	
    
      /* initialises the Channels and opens the graphic windows */
      pfCAVEInitChannels();
    
      /* generate a scene */
      scene = pfNewScene();
      dcs   = pfNewDCS();
      pfAddChild(scene, dcs);
      pfDCSTrans(dcs, 0.0, 100.0, 0.0);
      pfDCSScale(dcs, 50.0);
    
      geode = pfNewGeode();
      pfAddChild(dcs, geode);
      gs = pfdNewCube(pfGetSharedArena());
      pfAddGSet(geode, gs);
    
      /* attach scene to the CAVELib channels */
      chan = pfCAVEMasterChan();
      pfChanScene(chan, scene);
    
      /* start the simulation loop */
      pfInitClock(0.0);
      while (!CAVEgetbutton(CAVE_ESCKEY)) {
        /* update scene */
        pfDCSRot(dcs, 50.0*pfGetTime(), 0.0, 0.0);
    
        /* generate next frame */
        pfCAVEPreFrame(); pfFrame(); pfCAVEPostFrame();
      }
    
      /* halt the CAVELib */
      pfCAVEHalt();
    
      /* exit the Performer */
      pfExit();
    
      /* exit the Program */
      return(0);
    }
    

    Kompilieren eines Performer/CAVELib-Programmes

    Die CAVELib Header-Dateien liegen auf der merkur im Verzeichnis /usr/local/CAVE/include, dieser Pfad sollte dem C-Compiler mit folgendem Switch übergeben werden: -I/usr/local/CAVE/include

    Die CAVELib-Bibliotheken liegen im den Verzeichnissen /usr/local/CAVE/lib, /usr/local/CAVE/lib32 und /usr/local/CAVE/lib64. Je nachdem welche Art von Code erzeugt werden soll (-o32, -n32 oder -64), muß dem Compiler der jeweilige Pfad übergeben werden, mit zum Beispiel: -L/usr/local/CAVE/lib32.

    Die folgenden CAVELib/OpenGL-Bibliotheken müssen zu einem ausführbaren Programm gelinkt werden: -lpfcave_ogl -lcave_ogl -lGL -lX11 -lXi -lm

    Die folgenden Performer-Bibliotheken müssen zu einem ausführbaren Programm gelinkt werden: -lpfdu_ogl -lpfui -lpfutil_ogl -lpf_ogl

    Makefile

    Ein kleines Makefile-Tutorial

    Diese Makefile kompiliert das obige Beispielprogramm.

    Makefile.perf

    TARGET	= cube
    SRC	= $(TARGET).c
    
    CC	= cc
    CFLAGS  = -mips3 -n32 $(OPT) -I/usr/local/CAVE/include
    OPT	= -O 
    
    DEFS	= -DN32 -DIRIX6_5
    
    CAVELIB = -L/usr/local/CAVE/lib32 -lpf -lpfcave_ogl -lcave_ogl -lGL -lX11 -lXi -lm
    PERFLIB	= -lpfdu_ogl -lpfui -lpfutil_ogl -lpf_ogl
    
    LIBS	= -no_unresolved $(CAVELIB) $(PERFLIB) 
    
    $(TARGET): $(SRC)
    	$(CC) $(DEFS) $(CFLAGS) $? -o $@ $(LIBS)
    	
    run: $(TARGET)
    	$(TARGET)
    	
    clean:
    
    clobber:
    	rm -f $(TARGET)
    

    Laden einer Geometrie

    Der Performer stellt die Funktionalität zum Laden verschiedener Geometrieformate zur Verfügung.

    Das folgende Programm kann eine Geometrie im Inventor- (.iv) und im VRML2-Format (.wrl) laden und zeigt diese dann im CAVE an.

    Sourcecode zu loader.c und das dazugehörige Makefile.loader.

    /* includes*/
    #include <stdlib.h>
    #include <math.h>
    #include <Performer/pf.h>
    #include <Performer/pfdu.h>
    #include <Performer/pfutil.h>
    
    #include <cave_ogl.h>
    #include <pfcave.h>
    
    /* globals */
    
    /* prototypes */
    
    /* main */
    int main(int argc, char **argv) {
    
      pfScene	*scene;
      pfDCS		*dcs;
      pfGeode	*geode;
      pfGeoSet	*gs;
      pfChannel	*chan;
      char		*name;
      pfNode	*node;
      pfSphere	 bsphere;
      pfGeoState	*gstate;
    
      if (argc!=2) {
        fprintf(stderr, "usage: load filename\n\n");
        return(1);
      }
      name = argv[1];
    
      /* initialise the Performer */
      pfInit();
    
      /* configure the CAVELib */
      pfCAVEConfig(&argc, argv, NULL);	
    
      /* initialise the converter for the filetypes to load */
      pfdInitConverter("iv");
      pfdInitConverter("wrl");
    
      /* configure the Performer */
      pfConfig();	
    
      /* initialise the channels and open the graphic windows */
      pfCAVEInitChannels();
    
      /* generate a scene */
      scene = pfNewScene();
    
      /* enable and add lightsource to scene */
      gstate = pfNewGState(pfGetSharedArena());
      pfGStateMode(gstate, PFSTATE_ENLIGHTING, PF_ON);
      pfSceneGState(scene, gstate);
      pfAddChild(scene, pfNewLSource());
    
      dcs = pfNewDCS();
      pfAddChild(scene, dcs);
      pfDCSTrans(dcs, 0.0, 100.0, 0.0);
    
      node=pfdLoadFile(name); 
      if (!node) {
        fprintf(stderr, "could not load file'%s'\n", name);
    exit(1);
      }
    
      pfAddChild(dcs, node);
      pfNodeBSphere(node, NULL, PFBOUND_STATIC);
      pfGetNodeBSphere(node, &bsphere);
      if (bsphere.radius>0.0) pfDCSScale(dcs, 50.0/bsphere.radius);
      fprintf(stderr, "load: bsphere.radius %ff\n", bsphere.radius);
    
      /* attach scene to the CAVELib channels */
      chan = pfCAVEMasterChan();
      pfChanScene(chan, scene);
    
      /* start the simulation loop */
      pfInitClock(0.0);
      while (!CAVEgetbutton(CAVE_ESCKEY)) {
        /* update scene */
        pfDCSRot(dcs, 50.0*pfGetTime(), 0.0, 0.0);
    
        /* generate next frame */
        pfCAVEPreFrame(); pfFrame(); pfCAVEPostFrame();
      }
    
      /* halt the CAVELib */
      pfCAVEHalt();
    
      /* exit the Performer */
      pfExit();
    
      /* exit the Program */
      return(0);
    }
    


    next up previous
    Next: Performer (C++ API) Up: Programmieren mit der CAVELib Previous: OpenGL
    Mail to: Oliver Schönbrunner
    Virtual Reality Center