ok, i'm only using fvf's for a test of drawing dynamically height mapped ground quads, and for drawing meshes.
for the ground quad test, i'm using this vertex format:
const DWORD ZFVF=(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0) );
struct Zvertexrec
{
float x,y,z;
float nx,ny,nz;
float tu,tv;
DWORD diffuse,specular;
};
so these have position for drawing, normals for lighting, texture coords for texturing, and diffuse and specular lighting components.
but that was just a test.
in my actual code, i just call mesh.getfvf, and then call set_fvf. then i set my vertex and index buffers and call drawprimitive.
the meshes are made in truespace, and use its built-in .x export capability to save them as .x files. the .x files are loaded at program start, and are a convenient way for me to store vertex and index buffers for drawing.
as i recall, their vertex format is x,y,z,normal,u,v.
as i recall, diffuse and specular are only used when you're not texture mapping.
so here's the process:
1. figure out what you need. xyz, normal, u,v etc... xyz normal and uv might be enough for basic texturermapping and lighting.
2. declare your struct.
3. declare your fvf code dword (like my ZFVF above)
4. call set_fvf(myfvf_dword)