   Adding to an Unknown Vertex Structure
  I have a rather specific problem that I need to solve, so I'll try to be as specific as possible.. I'm developing a real-time graphics engine, with managed DirectX 9.0 and C#, that displays a scene filled with traffic (upwards of 800 low-poly cars on screen). As that's a fair number of cars, I'm working on batching them into groups (~25 cars in the vertex buffer each batch) and using HLSL effects to instance each of the batches. The trick with that process is that each vertex gets an integer packed in with it that tells it what car it belongs to in the batch. (I open up the mesh's vertex buffer, re-copy each vertex to a new buffer and include the special index at the same time). I then pass in an big array of position data as a global variable for the vertex shader. Using that extra "Instance ID" number that each vertex now has, the vertex shader knows what pieces of position data to pull out of the array and therein, where to place this particular vertex in the world.The problem I've run into is when I try to throw normal mapping on top of this process. I want to include Tangent and Binormal data in with the vertex information, so that I can use it in the shaders. The DX SDK installs a handy exporter plugin onto 3DS Max 7.0, and so I can export the Max car models into X-files. (The most recent Panda Exporter works with MAX 8.0 and doesn't appear to include Tangent/Binormal data) The Mesh.FromFile() call loads up those meshes nicely and the TANGENT and BINORMAL semantics are automatically hooked in for use in the shaders.*deep breath* Together, these two processes don't jive. I don't know the vertex layout that the MAX plugin is giving me and without it, I can't pack in the extra instancing data with each of the car mesh's verticies. Can anyone show me a way to examine the layout of a given mesh's vertex declaration or how to pick and place whatever components I need?   
  A couple options... both rely on manipulating the existing declaration.Ask the X file for it's vertex declaration.  Use GetDeclaration to get D3DVERTEXELEMENT9s.  Copy this to a new buffer, and append another item for your id, use CreateVertexDeclaration to make a new declaration, which you'll use when rendering.Because asking the X to render itself will likely set the old declaration, you may need to query the vertex and index buffers from the X, and render it yourself.  Many older samples did this, though as I don't use X files I can't be more specific... actually, if you're appending data you're likely already rendering on your own.Option 1.Put the id into a second vertex buffer, and use SetStreamSource to activate the second stream before rendering.  When appending to the declaration, put your data as a single float (or whatever) at offset 0 of stream 1.  Use a data item you know is free, such as specular, or finding the highest texcoord used in the existing declaration, and using the next texcoord for your id.Because the car data doesn't need modifying, you can memcpy the whole car at once, instead of copying vertex by vertex and modifying some of the data.  In the second stream, simply write the id number once per vertex.Option 2.Append the id into the declaration as above, but at the end of stream 0.  Create a new vertex buffer to hold data of the larger vertex size.  As you copy your meshes into this buffer, intermix the old vertex data and the id number.Option 3.Use instancing.  Requires shader 3 hardware, but can render any number of copies of a single car.  If you have 10 varieties of car, you'll only need to use 10 draw calls, regardless of how many cars are on screen.  A second stream is used to hold per instance data, such as world transform, color, texture coordinate transforms (to texture each instance differently).    This is useful if you're going to render many of the same car.Option 4.Like option 1 except instead of dynamically updating the VB based on what's visible, simply put several copies of the mesh into the VB/IB, each with your id.  When rendering just adjust the primitive count and numvertices to control how many copies are rendered at once.  This is useful if you're going to render many of the same car, like option 3.  This works on shader 1.1 hardware and uses only static vertex and index data.   ;  When I first approached the instancing problem, I took a look at the DX SDK instancing sample. Because the video hardware that I'm developing on doesn't support Shader 3.0, the "Hardware Instancing" method is out. I went with the "Shader Instancing" method pretty much exactly as it appears in that example. Also, I've an idea as to how I can load up two vertex buffers and set them to streams 0 and 1, but I don't know how to access that second stream from within my shaders. The more I research it, the more that ability seems to be an exclusivly Shader 3.0 feature.Addressing your suggestions, as I don't know what information is included in my original mesh verticies, I'm even finding it difficult to render these car meshes manually. I'll set the device's vertex and index buffers to that of the mesh and set the device's vertex declaration to a new declaration I create from the mesh's VertexElement array, but the sample car doesn't appear when I try to use DrawIndexedPrimitives.When it comes to creating and packing info into a new vertex buffer, I believe that the VertexBuffer constructor requires a "type" input. I'm under the impression that this calls for some predefined struct object that defines what pieces of data are included in each vertex.E.g.struct myVertex{Vector3 position;Vector3 color;float tu;float tv;};But again, I don't know the structure or contents of the mesh's verticies. (Strangely, the vertexdeclaration array Visual Studio pulls from the mesh during runtime is of dimension 65... That's quite a number of VertexElement definitions...)[Edited by - Rogue_Scholar on May 26, 2006 12:49:08 PM];  More mystery. I've stumbled across a strange bit of behaviour in the Mesh.DrawSubset() function. When I manually load up the car's vertex and index buffers, set the device's vertex declaration and vertex format to that of the mesh, and attempt to manually draw the car with DrawIndexedPrimitives, I get nothing. HOWEVER, if I draw the car first with a carMesh.DrawSubset(0) call, and THEN call DrawIndexedPrimitives, I get both cars drawn.This makes me think that DrawSubset might set some device RenderStates or something similar within itself. If anyone knows what those changes might be, I could probably then do them myself and be able to draw the car manually. That'd be one step closer to solving my "Instancing + Normal Mapping" problem.   