the terrain is stored in a single vertex buffer and index buffer.
Each terrain tile is laid out rectangularly in space (along the x/z axis) and is stored linearly in the vertex buffer.
the index buffer only contains indices for one tile, when drawing a tile we use the basevertex parameter to offset the indicies so it draws the proper tile, this saves a good amount of memory.
each vertex has
an XYZ position
a Normal vector
a diffuse color
and two sets of 2D texture coords
the first set of texture coords are set between 0 and 1 for the span of a tile.
the second set of texture coords are set between 0 and 1 for the span of the map.
The y (height) component of each vertex is computed by sampling a greyscale heightmap stored in system ram, each value is converted to a unit scale and then scaled by the heightScale setting of the map.
The engine manages a list of 'Materials' each material is a texture and a D3DMATERIAL9 structure (and likely other info later) base and splat tile properties are materials.
the terrain can have 1 to 4 'splat-maps' a splat-map is a large texture (1024x1024) with alpha only data (however since A8 is not supported on newer devices A4R4G4B4 or similar can be used).
each map determines the visiblity of splats that exist on the same layer, if you draw a path on the splat map 0, and set the splat0 slots of the relevant tiles to dirt, it will draw a dirt path for you.
this method of creating splats was to allow for tools such as photoshop to edit the maps, and because integrating an in-game tool for this would not be trivial.
The map is rendered in a few passes;
the base material's texture is placed into stage 0 and it's d3dmaterial is set, and the tiles are drawn one by one; this lays down the base terrain draw the base.
pass 1 to 4
if a splat-map is set it will try to render splats for that layer
the splat-map is set to texture stage 1 and the stage states are set to take alpha from this texture.
if a tile has it's splat set on the same level it will render the splat.
to render a splat, the splat material texture is pushed into stage 0 and is set to give color only.
the tile is drawn, and the splat color texture is masked by the splat alpha texture.
and that is basically how it works.
the engine maintains the 4 splat-map slots and when a map is switched it enables or disables the relavent splat slots and loads the proper texture in them.
this is conservation of memory (only 4 splat maps loaded at any one time) at the cost of per-map loading speed, but it shouldn't be an issue.
the engine maintains the materials as well, since they are all 256x256 in size, the could be atlased on-load at a later date but for now I have decided to keep them seperate, this should make it easy for the api to page them out if they are not used frequently.