Jim Helman (jimh++at++surreal)
Fri, 11 Mar 94 11:24:29 -0800
Here's a code fragment. Note that the code is inefficient in
that it only has one billboard polygon per pfBillboard node.
Several pfGeoSets would per pfBillboard be better.
rgds,
-jim helman
jimh++at++surreal.asd.sgi.com
415/390-1151
pfVec2 STexCoords[] ={{0.0f, 0.0f},
{1.0f, 0.0f},
{0.0f, 1.0f},
{1.0f, 1.0f}};
pfVec3 SVertCoords[] ={{-0.5f, 0.0f, 0.0f},
{ 0.5f, 0.0f, 0.0f},
{-0.5f, 0.0f, 1.0f},
{ 0.5f, 0.0f, 1.0f}};
long PrimLens[] = { 4 };
long seed = 0xe58a3e61;
pfGroup
*MakeBills(pfGroup *where, char **texNames, long nBills, float *sizes)
{
void *arena = pfGetSharedArena();
pfTexture *tex[MAX_BILL_TEX];
pfTexEnv *tenv;
pfGroup *group;
long i,j;
pfBox bbox;
float xorigin, yorigin;
float xrange, yrange;
pfCoord c;
pfGeode *geode;
char filepath[256];
long nVerts = 4;
long nTex = 0;
srand48(seed);
pfGetNodeBBox(where, &bbox, NULL);
xorigin = bbox.min[0];
yorigin = bbox.min[1];
xrange = bbox.max[0] - bbox.min[0];
yrange = bbox.max[1] - bbox.min[1];
tenv = pfNewTEnv(arena);
/* pfTEnvMode(tenv, PFTE_DECAL); */
for (i = 0 ; texNames[i] != NULL ; i++)
{
tex[i] = pfNewTex(arena);
if (!pfFindFile(texNames[i], filepath, R_OK))
{
fprintf(stderr, "WARNING: unable to find texture file \"%s\"\n",
texNames[i]);
return NULL;
}
if (!pfLoadTexFile(tex[i], filepath))
pfNotify(PFNFY_FATAL, PFNFY_RESOURCE,
"couldn't find %s\n", texNames[i]);
pfTexRepeat(tex[i], PFTEX_WRAP, PFTEX_CLAMP);
nTex++;
}
if (nTex == 0)
pfNotify(PFNFY_FATAL, PFNFY_RESOURCE, "no textures for billboards\n");
group = pfNewGroup();
for(i = 0, j = 0 ; i < nBills && j < 10 * nBills ; j++)
{
float p, r;
pfCoord pos;
pfVec4 *colors;
pos.xyz[0] = drand48() * xrange + xorigin;
pos.xyz[1] = drand48() * yrange + yorigin;
pfSetVec3(pos.hpr, 0.0f, 0.0f, 0.0f);
if (GetZPR((pfNode *)where, &pos, &pos.xyz[2], &p, &r))
{
long k;
pfVec3 *verts;
pfGeoSet *gset;
pfGeoState *gst;
pfBillboard *bill;
float size;
pfVec3 *posarr;
size = (drand48() * 0.5f + 0.5f) * sizes[i%nTex];
verts = (pfVec3 *)pfMalloc(sizeof(pfVec3)*nVerts, arena);
for (k = 0 ; k < nVerts ; k++)
pfScaleVec3(verts[k], size, SVertCoords[k]);
colors = (pfVec4 *)pfMalloc(sizeof(pfVec4), arena);
pfSetVec4(colors[0],
0.6f * drand48(), 0.4 + 0.4 * drand48(), 0.0f, 1.0f);
gset = pfNewGSet(arena);
pfGSetAttr(gset, PFGS_COORD3,
PFGS_PER_VERTEX, verts, NULL);
pfGSetAttr(gset, PFGS_TEXCOORD2,
PFGS_PER_VERTEX, STexCoords, NULL);
pfGSetAttr(gset, PFGS_COLOR4,
PFGS_PER_PRIM, colors, NULL);
pfGSetPrimLengths(gset, PrimLens);
pfGSetPrimType(gset, PFGS_TRISTRIPS);
pfGSetNumPrims(gset, 1);
gst = pfNewGState(arena);
pfGStateAttr(gst, PFSTATE_TEXTURE, tex[i%nTex]);
pfGStateAttr(gst, PFSTATE_TEXENV, tenv);
pfGStateMode(gst, PFSTATE_ALPHAFUNC, PFAF_NOTEQUAL);
pfGStateMode(gst, PFSTATE_ALPHAREF, 0);
pfGStateMode(gst, PFSTATE_ENLIGHTING, 0);
/* pfGStateMode(gst, PFSTATE_TRANSPARENCY,PFTR_ON); */
pfGSetGState(gset, gst);
bill = pfNewBboard();
pfAddGSet(bill, gset);
pfBboardPos(bill, 0, pos.xyz);
pfAddChild(group, bill);
i++;
}
}
if (i < nBills)
fprintf(stderr, "Only planted %d billboards\n", i);
return group;
}
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:50:12 PDT