Hi,
right what Samson said, it's a global for all formats.
It finally tells the GPU what data to expect. So in a normal scenario you would do this right before GX_Begin.
And by calling GX_ClearVtxDesc, before the chain of GX_SetVtxDesc calls for the used GX_VTXFMT, the current Vertex Descriptor setup gets cleared.
As an example i paste you the way i do it in wiirrlicht.
Here from the driver initialisation:
Code: Select all
//setup vtxfmt EVT_STANDARD
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
//setup vtxfmt EVT_2TCOORDS
GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX1, GX_TEX_ST, GX_F32, 0);
//setup vtxfmt EVT_TANGENT
GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_NBT, GX_NRM_NBT, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
And here how it's used later:
Code: Select all
void CGXDriver::drawVertexPrimitiveList(const void *vertices,u32 vertexCnt,const u16 *indices,u32 primitiveCnt,E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType,E_INDEX_TYPE iType)
{
u32 vtxfmt = GX_VTXFMT0;
u32 vtxmode = GX_DIRECT;
if(!primitiveCnt || !vertexCnt) return;
CNullDriver::drawVertexPrimitiveList(vertices,vertexCnt,indices,primitiveCnt,vType,pType,iType);
if(vertices==NULL) vtxmode = GX_INDEX16;
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS,vtxmode);
GX_SetVtxDesc(GX_VA_CLR0,vtxmode);
GX_SetVtxDesc(GX_VA_TEX0,vtxmode);
switch(vType) {
case EVT_STANDARD:
vtxfmt = GX_VTXFMT0;
GX_SetVtxDesc(GX_VA_NRM,vtxmode);
break;
case EVT_2TCOORDS:
vtxfmt = GX_VTXFMT1;
GX_SetVtxDesc(GX_VA_NRM,vtxmode);
GX_SetVtxDesc(GX_VA_TEX1,vtxmode);
break;
case EVT_TANGENTS:
vtxfmt = GX_VTXFMT2;
GX_SetVtxDesc(GX_VA_NBT,vtxmode);
break;
}
setRenderStates3DMode();
switch(pType) {
case scene::EPT_TRIANGLES:
drawVertexPrimitiveListGX(GX_TRIANGLES,vtxfmt,vertices,indices,primitiveCnt*3,vType);
break;
case scene::EPT_TRIANGLE_FAN:
drawVertexPrimitiveListGX(GX_TRIANGLEFAN,vtxfmt,vertices,indices,primitiveCnt+2,vType);
break;
case scene::EPT_LINE_STRIP:
drawVertexPrimitiveListGX(GX_LINESTRIP,vtxfmt,vertices,indices,primitiveCnt+1,vType);
break;
default:
break;
}
}
void CGXDriver::drawVertexPrimitiveListGX(u8 pType,u8 vtxfmt,const void *vertices,const u16 *indices,u16 primitiveCnt,E_VERTEX_TYPE vType)
{
u32 i;
GX_Begin(pType,vtxfmt,primitiveCnt);
switch(vType) {
case EVT_STANDARD:
{
if(vertices) {
const S3DVertex *v = reinterpret_cast<const S3DVertex*>(vertices);
for(i=0;i<primitiveCnt;i++) {
GX_Position3f32(v[indices[i]].pos.X,v[indices[i]].pos.Y,v[indices[i]].pos.Z);
GX_Normal3f32(v[indices[i]].nrm.X,v[indices[i]].nrm.Y,v[indices[i]].nrm.Z);
GX_Color4u8(v[indices[i]].col.getRed(),v[indices[i]].col.getGreen(),v[indices[i]].col.getBlue(),v[indices[i]].col.getAlpha());
GX_TexCoord2f32(v[indices[i]].tcoord.X,v[indices[i]].tcoord.Y);
}
} else {
for(i=0;i<primitiveCnt;i++) {
GX_Position1x16(indices[i]);
GX_Normal1x16(indices[i]);
GX_Color1x16(indices[i]);
GX_TexCoord1x16(indices[i]);
}
}
}
break;
case EVT_2TCOORDS:
{
if(vertices) {
const S3DVertex2TCoords *v = reinterpret_cast<const S3DVertex2TCoords*>(vertices);
for(i=0;i<primitiveCnt;i++) {
GX_Position3f32(v[indices[i]].pos.X,v[indices[i]].pos.Y,v[indices[i]].pos.Z);
GX_Normal3f32(v[indices[i]].nrm.X,v[indices[i]].nrm.Y,v[indices[i]].nrm.Z);
GX_Color4u8(v[indices[i]].col.getRed(),v[indices[i]].col.getGreen(),v[indices[i]].col.getBlue(),v[indices[i]].col.getAlpha());
GX_TexCoord2f32(v[indices[i]].tcoord.X,v[indices[i]].tcoord.Y);
GX_TexCoord2f32(v[indices[i]].tcoord2.X,v[indices[i]].tcoord2.Y);
}
} else {
for(i=0;i<primitiveCnt;i++) {
GX_Position1x16(indices[i]);
GX_Normal1x16(indices[i]);
GX_Color1x16(indices[i]);
GX_TexCoord1x16(indices[i]);
GX_TexCoord1x16(indices[i]);
}
}
}
break;
case EVT_TANGENTS:
{
if(vertices) {
const S3DVertexTangents *v = reinterpret_cast<const S3DVertexTangents*>(vertices);
for(i=0;i<primitiveCnt;i++) {
GX_Position3f32(v[indices[i]].pos.X,v[indices[i]].pos.Y,v[indices[i]].pos.Z);
GX_Normal3f32(v[indices[i]].nrm.X,v[indices[i]].nrm.Y,v[indices[i]].nrm.Z);
GX_Normal3f32(v[indices[i]].binrm.X,v[indices[i]].binrm.Y,v[indices[i]].binrm.Z);
GX_Normal3f32(v[indices[i]].tangent.X,v[indices[i]].tangent.Y,v[indices[i]].tangent.Z);
GX_Color4u8(v[indices[i]].col.getRed(),v[indices[i]].col.getGreen(),v[indices[i]].col.getBlue(),v[indices[i]].col.getAlpha());
GX_TexCoord2f32(v[indices[i]].tcoord.X,v[indices[i]].tcoord.Y);
}
} else {
for(i=0;i<primitiveCnt;i++) {
GX_Position1x16(indices[i]);
GX_Normal1x16(indices[i]);
GX_Color1x16(indices[i]);
GX_TexCoord1x16(indices[i]);
}
}
}
break;
default:
break;
}
GX_End();
}