Frederic Francis (pffred++at++llogic.com)
Thu, 20 Nov 1997 13:31:06 -0500 (EST)
>
> Ola Jorge,
>
> I think that the default geostate associated with instances of
> pfdNewSphere is the global one. So probably the best thing to do
> is to give it it's own and apply a texture on that geostate:
>
> pfGeoSet *s = pfdNewSphere(...);
> pfGeoState *g = new pfGeoState;
>
> // Attach geostate to geoset
> s->setGstate(g);
>
> // If you want to load a file from disk
> pfTexture *tex = new pfTexture; tex->loadFile("mytexturefile.rgb");
>
>
> // Apply texture
> g->setMode(PFSTATE_ENTEXTURE, PF_ON);
> g->setAttr(PFSTATE_TEXTURE, tex);
>
> // Define texture environment
> pfTexEnv *tenv = new pfTexEnv;
> tenv->setMode(PFTE_DECAL); // for example
> g->setAttr(PFSTATE_TEXENV, tenv);
>
>
>
> Best Regards,
>
> Fred.
>
Sorry Jorge,
I forgot that pfdSpheres have no texture coordinates.
For my penance:
Here is a program that makes a textured sphere uses an
equirectangular texture mapping. It uses a different
tesselation than pfdSphere but which is better for
equirectangular mappings. It also allows you to make
spherical sections.
Disclaimer: This code is a tad old but it seems to work.
Please give me a shout if it misbehaves.
Best Regards,
Fred.
__________________________________________________________________
Frederic Francis email: fred++at++llogic.com
Director of Technology phone: 1-514-287-1166
Lateral Logic fax: 1-514-287-3360
__________________________________________________________________
____________________________________________________________________
#include <stdlib.h>
#include <math.h>
#include <iostream.h>
#include <Performer/pfdu.h>
#include <Performer/pfdb/pfpfb.h>
#include <Performer/pr/pfTexture.h>
#include <Performer/pf/pfGeode.h>
#include <Performer/pr/pfGeoSet.h>
#include <Performer/pr/pfLinMath.h>
const double twoPi = 2.0 * M_PI;
const double oneOverPi = 1.0 / M_PI;
const double oneOverTwoPi = 1.0 / twoPi;
pfNode *makeSphereSection(int nTris, float minP, float maxP,
float minT, float maxT, char *texFile);
void main (int argc, char *argv[]) {
if ((argc > 8) || (argc < 7) )
{
cerr << " Usage: " << argv[0] << " outFile numTris minPhi
maxPhi minTheta maxTheta textureFile";
cerr << endl << endl << " Note: PI = 1 so phi's range is [0,2] and theta's range is [0,1]";
cerr << endl << " The last argument is optional, if no texture file is given the";
cerr << endl << " sphere is assigned tex coords but nothing is mapped onto it.";
cerr << endl << " The actual number of triangles will be greater than numTris.";
cerr << endl << endl;
}
else {
const int numTris = atoi(argv[2]);
float minPhi = atof(argv[3]);
float maxPhi = atof(argv[4]);
float minTheta = atof(argv[5]);
float maxTheta = atof(argv[6]);
char *textureFile = argv[7];
int goodPhi = ( (maxPhi > minPhi) && (minPhi >= 0.0) && (maxPhi <= 2.0) );
int goodTheta = ( (maxTheta > minTheta) && (minTheta >= 0.0) && (maxTheta <= 1.0) );
int goodTriNum = ( (numTris > 49) && (numTris < 500000) );
int cool = goodPhi && goodTheta && goodTriNum;
if ( !cool ) {
if ( (!goodPhi) || (!goodTheta) )
cerr << " Usage: pi = 1 so phi's range is [0,2] and theta's range is [0,1]" << endl;
if ( (!goodTriNum) )
cerr << " Usage: Number of triangles restricted between 50 and 500,000" << endl;
}
else {
pfInit();
pfMultiprocess(0);
pfConfig();
minPhi = minPhi * M_PI; minTheta = minTheta * M_PI;
maxPhi = maxPhi * M_PI; maxTheta = maxTheta * M_PI;
pfNode *s = makeSphereSection(numTris, minPhi, maxPhi, minTheta, maxTheta, textureFile);
pfdStoreFile_pfb(s, argv[1]);
pfExit();
}
}
}
pfNode *makeSphereSection(int numTris, float minPhi, float maxPhi,float minTheta, float maxTheta, char *textureFile) {
int numPrims = fceil(fsqrt(numTris));
int primLengths = 2 * (((numPrims + 2) + 1) / 2) ;
int numVertices = numPrims * primLengths;
float deltaPhi = (maxPhi - minPhi) / (0.5f * numPrims);
float deltaTheta = (maxTheta - minTheta) / numPrims;
pfGeode *sphere = new pfGeode;
pfGeoSet *sphereGset = new pfGeoSet;
pfGeoState *sphereGState = new pfGeoState;
pfVec3 *sphereCoords = (pfVec3 *) new(numVertices * sizeof(pfVec3)) pfMemory;
pfVec3 *sphereNorms = (pfVec3 *) new(numVertices * sizeof(pfVec3)) pfMemory;
pfVec4 *sphereColor = (pfVec4 *) new(sizeof(pfVec4)) pfMemory;
pfVec2 *sphereTexCoords = (pfVec2 *) new(numVertices * sizeof(pfVec2)) pfMemory;
int i,j,k;
float x,y,z,u,v;
float phi, theta;
theta = minTheta;
for(i=0;i<numPrims;i++) {
phi = minPhi;
for(j=0;j<primLengths;j+=2) {
k = j + i * primLengths;
x = cos(phi) * sin(theta);
y = sin(phi) * sin(theta);
z = cos(theta);
sphereCoords[k].set(x,y,z); sphereNorms[k].set(x,y,z);
sphereTexCoords[k][0] = phi * oneOverTwoPi;
sphereTexCoords[k][1] = 1.0f - (theta * oneOverPi);
k++;
x = cos(phi) * sin((theta + deltaTheta));
y = sin(phi) * sin((theta + deltaTheta));
z = cos((theta + deltaTheta));
sphereCoords[k].set(x,y,z); sphereNorms[k].set(x,y,z);
sphereTexCoords[k][0] = phi * oneOverTwoPi;
sphereTexCoords[k][1] = 1.0f - ((theta + deltaTheta) * oneOverPi);
phi += deltaPhi;
}
theta += deltaTheta;
}
sphereGset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, sphereCoords, NULL);
sphereGset->setAttr(PFGS_NORMAL3, PFGS_PER_VERTEX, sphereNorms, NULL);
sphereGset->setAttr(PFGS_TEXCOORD2, PFGS_PER_VERTEX, sphereTexCoords, NULL);
sphereColor[0].set(1.0f,1.0f,1.0f,1.0f);
sphereGset->setAttr(PFGS_COLOR4, PFGS_OVERALL, sphereColor, NULL);
int *spherePrimitivesLength = (int *) new(numPrims * sizeof(int)) pfMemory;
for(i=0;i<numPrims;i++) spherePrimitivesLength[i] = primLengths;
sphereGset->setPrimLengths(spherePrimitivesLength);
sphereGset->setPrimType(PFGS_TRISTRIPS);
sphereGset->setNumPrims(numPrims);
sphereGState->setMode(PFSTATE_ENTEXTURE, PF_ON);
if (textureFile) {
pfTexture *tex = new pfTexture; tex->loadFile(textureFile);
pfTexEnv *tenv = new pfTexEnv; tenv->setMode(PFTE_DECAL);
sphereGState->setAttr(PFSTATE_TEXTURE, tex); sphereGState->setAttr(PFSTATE_TEXENV, tenv);
}
sphereGset->setGState(sphereGState);
sphere->addGSet(sphereGset);
return(sphere);
}
=======================================================================
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:56:13 PDT