From: Hugues De Keyzer (hugues++at++depinxi.be)
Date: 07/08/2005 05:10:55
On Friday 8 July 2005 02:48, Stace Peterson wrote:
> Hugues,
>
> As you have noticed, pfGeoArrays don't support flat primitives. This is
> a limitation of the way that the OpenGL interfaces used for pfGeoArrays
> are setup, and is unlikely to change. I'll look into better documenting
> this case, however. Somewhat ironically, this case is actually the
> worst case for pfGeoArrays, since it demands extra specification of data
> which repeats vertex or normal data, but is typically never entirely
> equivalent (identical for all attributes), so it does not index or cache
> well.
The PFGS_FLAT_* primitives were in fact a "shortcut" to be able to render flat and non-flat primitives with the same pfGeoState. I understand that it could be removed because the shading model belongs actually in the pfGeoState.
But VBO's (and pfGeoArrays) completely support flat shading anyway. For a pfGeoArray with the normals specified for flat shading, that is, for a triangle strip, the normal of the ith face specified by the (2 + i)th vertex normal, if the PFSTATE_SHADEMODEL mode is set to PFSM_FLAT in the pfGeoState, the pfGeoArray is correctly flat-shaded. There is no performance penalty (at least for non-indexed pfGeoArray), since there is the same number of attributes per vertex than for smooth shading, the first two normals of the strip are simply ignored.
So, there is no problem to use flat shading with pfGeoArrays, the shading model simply has to be specified in the pfGeoState. Is this what we are supposed to do?
Maybe pfdBuilder should then be corrected to output that. The pf Town is uncorrectly shaded when loaded with the ".geoa" pseudo-loader.
Code for a correctly flat-shaded pfGeoArray tri-stripped cube:
pfGeode *geode = new pfGeode();
pfGeoArray *geoArray = new pfGeoArray();
pfGeoState *geoState = new pfGeoState();
pfMaterial *material = new pfMaterial();
pfVec3
a(-0.5, -0.5, -0.5),
b(0.5, -0.5, -0.5),
c(-0.5, 0.5, -0.5),
d(0.5, 0.5, -0.5),
e(-0.5, -0.5, 0.5),
f(0.5, -0.5, 0.5),
g(-0.5, 0.5, 0.5),
h(0.5, 0.5, 0.5),
A(0.0, 0.0, -1.0),
B(0.0, -1.0, 0.0),
C(1.0, 0.0, 0.0),
D(0.0, 1.0, 0.0),
E(-1.0, 0.0, 0.0),
F(0.0, 0.0, 1.0);
pfVec3 *varray = static_cast<pfVec3 *>(pfMemory::malloc(sizeof(pfVec3) * 14, SharedArena));
pfVec3 *narray = static_cast<pfVec3 *>(pfMemory::malloc(sizeof(pfVec3) * 14, SharedArena));
int *length = static_cast<int *>(pfMemory::malloc(sizeof(int), SharedArena));
pfVec3 *va = varray;
pfVec3 *na = narray;
memcpy(va++, &a, sizeof(pfVec3));
memcpy(na++, &E, sizeof(pfVec3));
memcpy(va++, &e, sizeof(pfVec3));
memcpy(na++, &E, sizeof(pfVec3));
memcpy(va++, &g, sizeof(pfVec3));
memcpy(na++, &E, sizeof(pfVec3));
memcpy(va++, &f, sizeof(pfVec3));
memcpy(na++, &F, sizeof(pfVec3));
memcpy(va++, &h, sizeof(pfVec3));
memcpy(na++, &F, sizeof(pfVec3));
memcpy(va++, &d, sizeof(pfVec3));
memcpy(na++, &C, sizeof(pfVec3));
memcpy(va++, &g, sizeof(pfVec3));
memcpy(na++, &D, sizeof(pfVec3));
memcpy(va++, &c, sizeof(pfVec3));
memcpy(na++, &D, sizeof(pfVec3));
memcpy(va++, &a, sizeof(pfVec3));
memcpy(na++, &E, sizeof(pfVec3));
memcpy(va++, &d, sizeof(pfVec3));
memcpy(na++, &A, sizeof(pfVec3));
memcpy(va++, &b, sizeof(pfVec3));
memcpy(na++, &A, sizeof(pfVec3));
memcpy(va++, &f, sizeof(pfVec3));
memcpy(na++, &C, sizeof(pfVec3));
memcpy(va++, &a, sizeof(pfVec3));
memcpy(na++, &B, sizeof(pfVec3));
memcpy(va, &e, sizeof(pfVec3));
memcpy(na, &B, sizeof(pfVec3));
// This has the same result than with PFGS_TRISTRIPS
//geoArray->setPrimType(PFGS_FLAT_TRISTRIPS);
geoArray->setPrimType(PFGS_TRISTRIPS);
geoArray->setNumPrims(1);
*length = 14;
geoArray->setPrimLengths(length);
geoArray->setAttr(PFGA_COORD_ARRAY, 3, GL_FLOAT, 0, varray);
geoArray->setAttr(PFGA_NORMAL_ARRAY, 3, GL_FLOAT, 0, narray);
material->setColor(PFMTL_AMBIENT, 0.75, 0.75, 0.75);
material->setColor(PFMTL_DIFFUSE, 0.75, 0.75, 0.75);
geoState->setMode(PFSTATE_ENLIGHTING, PF_ON);
geoState->setMode(PFSTATE_SHADEMODEL, PFSM_FLAT);
geoState->setMode(PFSTATE_CULLFACE, PFCF_BACK);
geoState->setAttr(PFSTATE_FRONTMTL, material);
geoArray->setGState(geoState);
geode->addGSet(geoArray);
geode->setName("myCube");
> As for the pfBillboard bug, thanks for bringing it to our attention and
> I will look into it for you.
>
> Thanks for your comments.
> Stace
Thanks for your reply.
Hugues
This archive was generated by hypermail 2b29 : Fri Jul 08 2005 - 05:12:15 PDT