Sam Chu (c00chu00++at++nchc.gov.tw)
Tue, 17 Jun 1997 08:37:52 +0800 (CST)
I still try to figure out how to display texture for some special
objects(trees)using this method. Maybe someone can give me a advise?
thanks.
/*--------------------------------------------------------------
* irsim.c - Skeleton program for lab exersizes
* Adding the code segment from the MultiGen Newletter
* Vol 3-1, 3-2 and 4-1
*/
#include <Performer/pf.h>
#include <Performer/pfui.h>
#include <Performer/pfutil.h>
#include <Performer/pfdu.h>
#include <Performer/pfdb/pfflt.h>
#include <stdlib.h>
#include <stdio.h>
/*==================
* Types
*=================*/
typedef struct {
void *arena;
pfScene *pScene;
pfDCS *pSceneDCS; /* DCS for trackball interface */
pfPipeWindow *pPWindow;
int winType;
int inputType;
pfChannel *pMainChannel;
pfChannel *pIRChannel;
float near, far;
pfCoord startPos;
pfiTDFXformer *pXformer;
pfuMouse mouse;
pfuEventStream events;
int exitFlag;
int litFlag;
int txtFlag;
} SharedState;
/*========================
* Prototypes
*========================*/
void setupSharedState(void);
void setupWindow(void);
void openPipeWindowCB(pfPipeWindow *);
void setupSceneGraph(void);
void setupChannel(void);
void initViewPos(void);
void printBBoxSize(pfBox *);
float calcMaxSize(pfBox *);
void setupInputHandling(void);
void updateView(void);
void updateSim(void);
void processKeybdInput(void);
void showHelp(void);
void initInfraredChan(pfChannel *);
void InfraRedMaterials(fltSharedPalette *);
void SetEmissive(pfMaterial *, int);
void drawCB(pfChannel *, void*);
void changeStates(void);
/*=====================
* Globals
*====================*/
SharedState *pState;
int notifyLevel = PFNFY_WARN; /* Level of msgs printed */
char title[256];
/*=======================
* main()
*=======================*/
int main(int argc, char *argv[])
{
pfPipe *pPipe;
/****************************************************************
* Initialize performer and shared info
****************************************************************/
pfInit(); /* Init performer (pf) */
pfNotifyLevel(notifyLevel);
pState = (SharedState*)pfCalloc(1, sizeof(SharedState), pfGetSharedArena());
setupSharedState();
pfMultiprocess(PFMP_APP_CULL_DRAW);
pfConfig(); /* fork? processes */
pfiInit(); /* Init input processing (pfui) */
pfuInitUtil(); /* Init utilities (pfutil) */
/*********************************************
* Set up simulation
*********************************************/
sprintf(title, "%s MOUSE: L=accel M=steer R=decel"
" KEYS: <h> help", argv[0]);
setupWindow(); /* Create & open a window */
setupSceneGraph(); /* Build database */
setupChannel(); /* Set up a view into database */
setupInputHandling(); /* Prepare to handle input */
pfChanTravFunc(pState->pMainChannel, PFTRAV_DRAW, drawCB);
pfChanTravFunc(pState->pIRChannel, PFTRAV_DRAW, drawCB);
/*********************************************
* Simulation loop
*********************************************/
while ( !pState->exitFlag ) {
updateSim(); /* Handle rest of info */
pfSync(); /* Wait until next frame */
updateView(); /* Collect time critical info */
pfFrame(); /* Process/draw the frame */
}
/********************************************
* Clean-up
********************************************/
pfuExitUtil();
pfuExitGUI();
pfuExitInput();
pfExit();
return 0;
}
/*===============================
* Shared Memory Functions
*===============================*/
void setupSharedState(void)
{
pState->arena = pfGetSharedArena();
pState->winType = PFWIN_TYPE_X;
pState->inputType = PFUINPUT_X;
pState->near = 0.5f;
pState->far = 10.0f;
pState->litFlag = 1;
}
/*=============================
* Window functions
*============================*/
void setupWindow(void)
{
pState->pPWindow = pfNewPWin(pfGetPipe(0));
pfPWinName(pState->pPWindow, title);
pfPWinType(pState->pPWindow, pState->winType);
pfPWinOriginSize(pState->pPWindow, 0, 0, 1000, 800);
pfPWinConfigFunc(pState->pPWindow, openPipeWindowCB);
pfConfigPWin(pState->pPWindow);
pfFrame();
}
/**** openPipeWindow(): callback to create window *********/
void openPipeWindowCB(pfPipeWindow *pw)
{
pfOpenPWin(pw);
}
/**** Draw Process Callback ******/
void drawCB(pfChannel *chan, void *data)
{
/* Make GL state changes in draw process */
changeStates();
/* You must asked to clear your own framebuffer */
pfClearChan(chan);
/* You must ask to draw your scene */
pfDraw();
(data);
}
void changeStates(void)
{
static int lastLitFlag=1;
static int lastTxtFlag=1;
if ( pState->litFlag != lastLitFlag ) {
if ( pState->litFlag ) {
/* Enable lighting for lit objects */
pfOverride(PFSTATE_ENLIGHTING, PF_OFF);
pfEnable(PFEN_LIGHTING);
printf("Enable lighting\n");
} else {
/* Disable lighting for all objects */
pfOverride(PFSTATE_ENLIGHTING, PF_OFF);
pfDisable(PFEN_LIGHTING);
pfOverride(PFSTATE_ENLIGHTING, PF_ON);
printf("Disable lighting\n");
}
lastLitFlag = pState->litFlag;
}
if ( pState->txtFlag != lastTxtFlag ) {
if ( pState->txtFlag ) {
/* Enable texture for texture objects */
pfOverride(PFSTATE_ENTEXTURE, PF_OFF);
pfEnable(PFEN_TEXTURE);
printf("Enable texture\n");
} else {
/* Disable texture for all objects */
pfOverride(PFSTATE_ENTEXTURE, PF_OFF);
pfDisable(PFEN_TEXTURE);
pfOverride(PFSTATE_ENTEXTURE, PF_ON);
printf("Disable texture\n");
}
lastTxtFlag = pState->txtFlag;
}
}
/*=============================
* Scene graph functions
*============================*/
void setupSceneGraph(void)
{
pfNode *pModelRoot;
pfLightSource *pSun;
char *filename;
pfFilePath("."
":../data"
":../pf_data"
":../pf_friends/town/orig/pfmodel"
":../pf_friends/town/orig/pftexture"
":../pf_friends/town/orig/pftown"
":/usr/share/Performer/data"
":/usr/share/Performer/friends/town/orig/pfmodel"
":/usr/share/Performer/friends/town/orig/pftexture"
":/usr/share/Performer/friends/town/orig/pftown"
);
pState->pScene = pfNewScene();
pSun = pfNewLSource(); /* Create a light to see by */
pfAddChild(pState->pScene, pSun);
pState->pSceneDCS = pfNewDCS();
pfAddChild(pState->pScene, pState->pSceneDCS);
pfdConverterMode("flt", PFFLT_GSTATE_TABLES,2); /* IR */
filename = "m48_ir1.flt";
if ( (pModelRoot = pfdLoadFile_flt(filename)) == NULL ) {
pfNotify(PFNFY_FATAL, PFNFY_USAGE, "Failed to read %s\n", filename);
}
pfAddChild(pState->pSceneDCS, pModelRoot);
}
/*=============================
* Channel/view functions
*============================*/
void setupChannel(void)
{
pfList *gsList;
fltSharedPalette *palette;
fltRenderMap *rendMap;
/*** Create and connect channel to window & scene graph ****/
pState->pMainChannel = pfNewChan(pfGetPipe(0));
pfChanScene(pState->pMainChannel, pState->pScene);
pState->pIRChannel = pfNewChan(pfGetPipe(0));
pfChanScene(pState->pIRChannel, pState->pScene);
/**** Set channel's viewing volume and position ****/
initViewPos();
pfChanFOV(pState->pMainChannel, 45.0f, -1.0f);
pfChanViewport(pState->pMainChannel, 0.0f, 0.5f, 0.0f, 1.0f);
pfChanNearFar(pState->pMainChannel, pState->near, pState->far);
pfChanView(pState->pMainChannel, pState->startPos.xyz,
pState->startPos.hpr);
pfChanFOV(pState->pIRChannel, 45.0f, -1.0f);
pfChanViewport(pState->pIRChannel, 0.5f, 1.0f, 0.0f, 1.0f);
pfChanNearFar(pState->pIRChannel, pState->near, pState->far);
pfChanView(pState->pIRChannel, pState->startPos.xyz,
pState->startPos.hpr);
/* for normal and IR Channel's shared object sutup*/
palette = fltGetCurSharedPalette();
rendMap = palette->rendMap;
gsList = pfGet(rendMap->renditions, 0);
pfChanGStateTable(pState->pMainChannel, gsList);
gsList = pfGet(rendMap->renditions, 1);
pfChanGStateTable(pState->pIRChannel, gsList);
InfraRedMaterials(palette);
}
/**** initViewPos(): calculates starting view position ***********/
void initViewPos(void)
{
pfBox sceneBBox;
float goodViewDist;
pfNode *pModelRoot;
/**** Find size of scene *****/
pfuTravCalcBBox(pState->pScene, &sceneBBox);
printBBoxSize(&sceneBBox);
/**** Calculate center of database ********/
pfAddVec3(pState->startPos.xyz, sceneBBox.min, sceneBBox.max);
pfScaleVec3(pState->startPos.xyz, 0.5f, pState->startPos.xyz);
/**** Pull back for good view ****/
goodViewDist = 1.3 * calcMaxSize(&sceneBBox);
pState->far = 3.8 * goodViewDist;
pState->startPos.xyz[PF_Y] -= goodViewDist;
/**** Set direction of view ****/
pfSetVec3(pState->startPos.hpr, 0.0f, 0.0f, 0.0f);
}
void printBBoxSize(pfBox *pb) /* Prints box size for debugging */
{
pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "Bounding box of object is:\n");
pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\t\tAxis: Minimum\tMaximum\n");
pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\t\t-------------------------\n");
pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\t\t X: %8.2f\t%8.2f\n",
pb->min[PF_X], pb->max[PF_X]);
pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\t\t Y: %8.2f\t%8.2f\n",
pb->min[PF_Y], pb->max[PF_Y]);
pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\t\t Z: %8.2f\t%8.2f\n",
pb->min[PF_Z], pb->max[PF_Z]);
pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\n");
}
float calcMaxSize(pfBox *pb) /**** calc length of longest dim ****/
{
float result;
result = pb->max[PF_X] - pb->min[PF_X];
result = PF_MAX2(result, pb->max[PF_Y] - pb->min[PF_Y]);
result = PF_MAX2(result, pb->max[PF_Z] - pb->min[PF_Z]);
return result;
}
/*=====================================
* Simulation/input functions
*=====================================*/
void setupInputHandling(void)
{
/**** Set the type of input processing. X or GL? ****/
pfuInitInput(pState->pPWindow, pState->inputType);
/**** Create a transformer ****/
pState->pXformer = (pfiXformer *)pfiNewTDFXformer(pfGetSharedArena());
/**** Set initial and reset position for xformer ****/
pfiXformerCoord(pState->pXformer, &pState->startPos);
/**** Xformer will get its input from buffers mouse & events ****/
pfiXformerAutoInput(pState->pXformer, pState->pMainChannel,
&pState->mouse, &pState->events);
pfiXformerNode(pState->pXformer, pState->pScene);
pfiXformerResetCoord(pState->pXformer, &pState->startPos);
/**** Xformer's results automatically change channels position ****/
pfiXformerAutoPosition(pState->pXformer, pState->pMainChannel, pState->pSceneDCS);
/**** Use TRACKBALL model ****/
pfiSelectXformerModel(pState->pXformer, PFITDF_TRACKBALL);
}
void updateView(void) /**** Time sensitive updates ****/
{
pfCoord view;
pfuGetMouse(&pState->mouse); /* Record mouse position */
pfiUpdateXformer(pState->pXformer); /* Update Xformer */
pfiGetIXformCoord(pState->pXformer, &view);
pfChanView(pState->pIRChannel, view.xyz, view.hpr);
}
void updateSim(void) /**** Costlier updates ****/
{
pfuGetEvents(&pState->events); /* Read keyboard events */
processKeybdInput(); /* Process these events */
}
void processKeybdInput(void)
{
int i, j;
int key, dev, val, numDevs;
pfuEventStream *pEvents;
pEvents = &pState->events;
numDevs = pEvents->numDevs;
for ( j=0; j < numDevs; ++j) {
dev = pEvents->devQ[j];
val = pEvents->devVal[j];
if ( pEvents->devCount[dev] > 0 ) {
switch ( dev ) {
case PFUDEV_REDRAW:
pEvents->devCount[dev] = 0;
break;
case PFUDEV_WINQUIT:
pState->exitFlag = 1;
pEvents->devCount[dev] = 0;
break;
case PFUDEV_KEYBD:
for ( i=0; i < pEvents->numKeys; ++i ) {
key = pEvents->keyQ[i];
if ( pEvents->keyCount[key] ) {
switch ( key ) {
case 27: /* ESC key. Exits prog */
pState->exitFlag = 1;
break;
case 'R':
case 'r': /* Reset position */
pfiStopXformer(pState->pXformer);
pfiResetXformerPosition(pState->pXformer);
break;
case 'H':
case 'h':
showHelp();
break;
case 'L':
case 'l':
pState->litFlag = !pState->litFlag;
break;
case 'T':
case 't':
pState->txtFlag = !pState->txtFlag;
break;
default:
break;
}
}
}
pEvents->devCount[dev] = 0;
break;
default:
break;
}
}
}
pEvents->numKeys = 0;
pEvents->numDevs = 0;
}
void showHelp(void)
{
system("xconfirm "
" -h Help"
" -icon info"
" -t \"Esc Quit\""
" -t \"r/R Reset position\""
" -t \"h/H Help\""
" -font \"-*-screen-bold-r-*-*-15-*-*-*-*-*-*-*\""
" > /dev/null &");
}
static void
SetEmissive(pfMaterial *mtl, int keyValue)
{
float red = 0.0f;
float gre = 0.0f;
float blu = 0.0f;
printf("(SetEmissive) keyValue = %d\n", keyValue);
switch (keyValue) { /* face IR Material index */
case 1: /* white hot */
red = 1.0f;
gre = 1.0f;
blu = 1.0f;
break;
case 2: /* red warm */
red = 0.7f;
gre = 0.1f;
blu = 0.1f;
break;
case 3: /* blue cool */
red = 0.1f;
gre = 0.1f;
blu = 0.5f;
break;
case 4: /* dark grey cold */
red = 0.1f;
gre = 0.1f;
blu = 0.1f;
break;
case 100: /* Tank ir color */
red = 0.0f;
gre = 0.7f;
blu = 0.2f;
break;
case 101: /* Tank ir color */
red = 0.8f;
gre = 0.3f;
blu = 0.4f;
break;
}
pfMtlColor(mtl, PFMTL_EMISSION, red, gre, blu);
}
static void
InfraRedMaterials(fltSharedPalette *palette)
{
pfList *matList = palette->matList;
int howMany = pfGetNum(matList);
int which;
for (which = 0; which < howMany; ++which) {
fltSharedObj *obj = pfGet(matList, which);
printf("which=%d\n", which);
if (obj->key.attr == FLTA_IRMATERIAL) {
/*material mode is PFMTL_CMODE_COLOR */
pfMaterial *mtl = (pfMaterial *)obj->object;
SetEmissive(mtl, obj->key.value);
}
}
}
Sam Chu
National Center for High-Performance Computing
Scientific Visualization Lab Email: c00chu00++at++nchc.gov.tw
Tel: (886)35-776085 Ext 248 Fax : (886)35-773538
=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
Submissions: info-performer++at++sgi.com
Admin. requests: info-performer-request++at++sgi.com
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:55:27 PDT