[pascal]
type
PVec3 = ^TVec3;
TVec3 = record x, y, z: Single; end;
TFace = array[0..2] of DWord;
TMeshPositions = array of TVec3;
TMeshFaces = array of TFace;
PIndex2 = ^TIndex2;
TIndex2 = array[0..0] of Word;
PIndex4 = ^TIndex4;
TIndex4 = array[0..0] of DWord;
...
var
Positions: TMeshPositions;
Faces: TMeshFaces;
Mesh: ID3DXMesh;
Vertices: Pointer;
VertexStride: Word;
Indices2: PIndex2;
Indices4: PIndex4;
MeshOptions: DWord;
i: Integer;
...
MeshOptions := Mesh.GetOptions;
SetLength(Positions, Mesh.GetNumVertices);
SetLength(Faces, Mesh.GetNumFaces);
VertexStride := Mesh.GetNumBytesPerVertex;
Mesh.LockVertexBuffer(D3DLOCK_READONLY, Vertices);
for i := 0 to High(Positions) do
Positions[i] := PVec3(
Pointer(Cardinal(Vertices) + i * VertexStride)
)^;
//Unless you use a custom vertex declaration in your mesh
//it is safe to assume that the first 12 bytes are vertex positions.
Mesh.UnlockVertexBuffer;
//Depending on the size of indices (16 or 32 bit) use an
//appropriate typed pointer (Indices2 or Indices4).
if MeshOptions and D3DXMESH_32BIT = D3DXMESH_32BIT then
begin
Mesh.LockIndexBuffer(D3DLOCK_READONLY, Pointer(Indices4));
for i := 0 to High(Faces) do
begin
Faces[i][0] := Indices4^[i * 3];
Faces[i][1] := Indices4^[i * 3 + 1];
Faces[i][2] := Indices4^[i * 3 + 2];
end;
end
else
begin
Mesh.LockIndexBuffer(D3DLOCK_READONLY, Pointer(Indices2));
for i := 0 to High(Faces) do
begin
Faces[i][0] := Indices2^[i * 3];
Faces[i][1] := Indices2^[i * 3 + 1];
Faces[i][2] := Indices2^[i * 3 + 2];
end;
end;
Mesh.UnlockIndexBuffer;
[/pascal]
After that you can easily find your triangles like this:
Positions[Faces[0][0]]; Positions[Faces[0][1]]; Positions[Faces[0][2]]; //for the first triangle
Positions[Faces[n][0]]; Positions[Faces[n][1]]; Positions[Faces[n][2]]; //for n'th triangle

There may be some minor errors in the code since I just typed it in the forum and haven't checked it myself.