This is an old question, but I had to figure this out myself yesterday so I thought I'd post a followup:
If you're using the default FBX content processor and have the DefaultEffect property set to BasicEffect, you can get the Texture2D for the object via:
texture = ((BasicEffect)model.Meshes[0].Effects[0]).Texture;
Note that the each mesh in the model may have a different texture.
The texture coordinates are stored in the MeshPart'sVertexBuffer along with position, etc. I've seen two vertex declarations. For a model/mesh that used a single texture (bitmap material in 3DS Max), the vertex declaration was VertexPositionNormalTexture.
For a model that had two textures (a bitmap and an opacity/alpha map), the declaration had the elements:
Position
Normal
Texture (usage index 0)
Texture (usage index 1)
or, wrapped into an IVertexType structure,
public struct VertexPositionNormalTextureTexture : IVertexType
{
public Vector3 Position;
public Vector3 Normal;
public Vector4 Texture0;
public Vector4 Texture1;
public static VertexDeclaration VertexDeclaration
{
get
{
return new VertexDeclaration
(
new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.Position, 0)
,
new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.Normal, 0)
,
new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 0)
,
new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 1)
);
}
}
VertexDeclaration IVertexType.VertexDeclaration
{
get { return VertexDeclaration; }
}
}
and the equivelant HLSL structure:
struct VertexPositionNormalTextureTexture
{
float3 Position : POSITION0;
float3 Normal : NORMAL0;
float4 Texture0 : TEXCOORD0;
float4 Texture1 : TEXCOORD1;
};
Note that I changed .Position and .Normal from Vector4 and Vector3 to float4 and float3 before I posted this, and haven't tested it. It's possible that they may need to be changed back to Vector4 and float4.
Of course, you'll need a sampler and some basic logic in your pixel shader to read each texture. Assuming you've set two effect parameters xTexture0 and xTexture1 to Texture2D objects containing your color texture and opacity map,
// texture sampler
sampler Sampler0 = sampler_state
{
Texture = (xTexture0);
};
sampler Sampler1 = sampler_state
{
Texture = (xTexture1);
};
and here's a simple two-texture pixel shader. If you only want one texture, just read from the first sampler and return the value, or apply lighting, etc.
float4 TwoTexturePixelShader(VertexPositionNormalTextureTexture input) : COLOR0
{
float4 texel0;
float4 texel1;
float4 pixel;
// check global effect parameter to see if we want textures turned on
// (useful for debugging geometry weirdness)
if (TexturesEnabled)
{
texel0 = tex2D(Sampler0, input.Texture0);
texel1 = tex2D(Sampler1, input.Texture1);
/// Assume texel1 is an alpha map, so just multiple texel0 by that alpha.
pixel.rgb=texel0.rgb;
pixel.a=texel0.a;
}
else
/// return 100% green
pixel = float4(0,1,0,1);
return pixel;
}
The relevant points here are that the texture coordinates are already present in the FBX and are already stored in each MeshPart's VertexBuffer, so all you need to do is extract the texture, pass it into your shader as a global effect parameter, and proceed as normal.