Fog

New Message Reply Date view Thread view Subject view Author view

Jim Helman (jimh++at++surreal)
Fri, 11 Mar 94 11:24:29 -0800


Try turning off backface culling, perhaps they are backwards?
I think the 1.0 man page may have been incorrect about the
orientation.

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;
}


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:50:12 PDT

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