2000 polys (tris) = 1000 quads.
say 5 textures to blend, one base, 4 splat.
and 4 tiles per texture.
and say 4 types of blendmaps (different blending patterns - alphamaps).
texture size 256x256.
one texture per quad, no wrap, etc.
you'd need 20 texture tiles and 4 alphamaps.
one pass in HLSL per quad, or 5 passes in retained mode (i think - double check me on these numbers, it may be 5 passes in HLSL too if you want to use any alphamap for any splat operation. )
the size of your quads will the determine the granularity of your splats.
make the quads as small as needed to get the splat size you want.
if the resulting mesh is too many triangles, then its time to think LOD strategies, I'd say. such as a high rez mesh around the camera surrounded by a ring of lower rez meshes out to the horizon, or perhaps something as simple as only splat out to 1/2 the distance to the far clip plane or something like that.
my drawground() routine doesn't do splatting. the game uses the fixed function pipeline (so far) for maximum compatibility, and there's so much vegetation in most areas you can't even see the ground texture. that whole one extra pass per texture thing put me off. i may end up doing a little bit of it though, where the ground is visible and boring (and not supposed to be boring, like endless dunes of sand).
in the end, splatting is just another technique for procedurally generating a texture for a ground quad. ground quad size and the number of times you repeat the texture across the quad will still determine the final resolution of the ground tiles. the method of texture generation is irrelevant.
another trick to getting small spats while using large underlying quads:
i used this technique in "Combat racer" to draw dirt roads etc:
1. draw the underlying ground mesh with the base texture.
2. instead of splatting a second texture onto a quad, you draw a quad any size you want , anywhere you want, just above the ground, and texture it with your splat texture, either with an alpha blend, or an alpha test.
this way you only overdraw quads where you want splat, splat quads can be any size, and at any location relative to the underlying ground quads. the only trick is to watch out for z fighting if you draw too close to the ground mesh. you can also use a 3d mesh for the splat instead of a flat quad, to do effects like a slightly raised brick path, etc.
in the end, this is simply drawing special terrain as separate meshes over top the ground mesh.
if you want to get really fancy, blend the textures yourself, then draw. that way you can blend a small splat onto a big underlying ground texture, and use big ground quads.
in the previous version of my current project i used a 10 channel real time weighted texture blender for ground textures, with a 10 texture cache.
you'd make a call to the texture blender , passing it say, 4 textures (all i needed for that project), and 4 weights (blend factors 0-100%). if it already had one like that blended in the cache, it returned that texture, otherwise it would blend the new texture and add it to the cache (LRU algo). then you locked a blank texture, copied the whole thing into the texture, set texture, and draw. texture data structures were not used for the blender or cache, just 2d arrays of RGB char structs. you only mess with textures, locking, etc, when you copy the results.
you could use a similar technique.
start with your underlying ground texture in the blending buffer.
have a routine that does a splat. you pass it the tex coords for the center or UL corner of the splat, the splat texture, and the alphamap. it does the blend:
buf=buf*(1-blendfacor)+splat*blendfactor (is that right?) for r,g,b , for each texel.
make a call for each desired splat.
then copy the buffer to a texture and draw your quad.
you would have to draw quads one at at time, or in sections, say 4x4 quads, blending 16 textures first, then using them to texture the 16 quads in your 4x4 quad ground mesh.
if you wanted to get really crazy, you could just have one huge texture for the whole ground mesh. blend the whole thing in a big buffer first, then copy it to a huge empty texture, set texture, draw ground mesh, done! but th vidcard may not like your huge texture. I've tested using high rez textures up to about 1024x1024 with no problems.
a 2048 triangle ground mesh is 32 quads across. at 256x256 texture size, thats 32x256=8K texels across. so a texture for the whole ground mesh would only be an 8K by 8K texture.
your statement of "low poly, <2000" is somewhat vague.
if in fact you have something more like a 50x50 quad ground mesh, thats 2500 quads (ploys), or 5000 tris. at 256x256 texture size, it would be 50*256= 12800 texels (12k?) across. the vidacrd may or may not be able to handle a 12k by 12k texture. i come up with 576 meg for the texture size at 12k by 12k.
me personally, i'd probably write a blender/splater thing like i described that does a one quad texture, and just draw each quad. if splat patterns repeat i'd use a cache too.
gets you everything you want at the price of a single texture lock per splat pattern (a pattern of splats on quad, not a single splat), and a single mesh lock per quad draw (remember, you have to height map each quad before drawing it).
i'd use a circular buffer to hold blended textures, a circular buffer of empty D3DXtextures to copy the blend results into, and a circular buffer of ground quads to height map.
for storing the splat info, i'd probably use a sparse matrix, an array of structs with: quad coords of the splat, texel coords of the center of the splat in the quad, splat texture ID #, and alpha map ID #.
to draw a quad, you'd go through the sparse matrix and look for records with matching quad coords. for each match, use the texel coords and texture and alphamap ID#'s to call your splat blend routine. copy the result to a texture, then set texture, height map the quad, and draw.
sorting the sparse matrix list on quad x,z and stopping your search once you passed the x,z of the quad in question is the standard optimization used for this type of search.
wow!! i think i may just have to build that, sounds cool! <g>.