Quote: "i didn't notice anything wrong with distant clusters on my ati card as mentioned in the readme but i'm not sure what to look for."
Maybe it only affects some ATI cards, one of my testers had some model of the 4850(I don't remember exactly) and he reported not noticing any size variation in the leaf clumps, so when you got closer you could see all the branches and the leaves were all tiny. Apparently this doesn't affect all ATI cards so no idea, I'll be implementing some proper billboard leaves eventually.
Quote: "everything looked natural to me except when approaching distant trees; they appear to lean (exactly?) the opposite way compared to their distant versions."
The distant LOD billboards only use a single texture for all trees of the same type(of which there are 3), I didn't take into account the rotation of the higher detail tree and rotate the billboard so I'll add this in. However they sway the exact same as the higher detail ones. Eventually I'll make it so that the distance LOD billboards use snapshots from multiple angles of the high detail tree so it looks as close to the highest detail one as possible at all times.
Quote: "I just noticed it made a huge performance drop when adding the grass though, from 75fps to about 50fps"
Yep, adding grass shouldn't be done more than once unless your PC can handle all the additional fillrate. Though if you get close to the ground you can see that there's quite a lot to draw.
Quote: "What kind of control will we have with using it in GDK? Because this would be a great addition for me if I can use it properly"
It depends for what, adding trees and static props(rocks, logs etc) gives you full control over the amount of instances of that type of thing, their rotation, scale and position. Things like trees can be repositioned and re-rotated at any time however instances of an object group can't but I can easily add that in.
The way objects that follow the camera are handled is slightly different, you select the size of each foliage cell and the amount of cells on the X/Z axis, the amount of instances in each cell and the source objects. These automatically follow the camera around and thus you don't have control over their placement(though you initially do) but their placement uses a function callback so you can tell the engine what the terrain height is at that location and you can return false if you don't want foliage spawning there and it is hidden for this cell.
Here's an excerpt from main.cpp of the demo that spawns the grass(it creates 3 instances of 2 types):
foliage.CreateTileShiftArray( groupGrass, 0, 50, 1, 15.0f, 3, &D3DXVECTOR3(2.0f,3.0f,2.0f), &D3DXVECTOR3(3.0f,6.0f,3.0f), &D3DXVECTOR3(5.0f,360.0f,5.0f) );
foliage.CreateTileShiftArray( groupGrass, 1, 25, 1, 10.0f, 3, &D3DXVECTOR3(2.0f,1.0f,2.0f), &D3DXVECTOR3(3.0f,1.5f,3.0f), &D3DXVECTOR3(5.0f,360.0f,5.0f) );
foliage.CreateTileShiftArray( groupGrass, 1, 25, 1, 20.0f, 3, &D3DXVECTOR3(2.0f,1.0f,2.0f), &D3DXVECTOR3(3.0f,2.5f,3.0f), &D3DXVECTOR3(5.0f,360.0f,5.0f) );
and the declaration for this CreateTileShiftArray method is:
void FoliageHandlerBase::CreateTileShiftArray( int groupID, int LODID, int instancesPerSection, int meshID, float sectionSize, int radius, D3DXVECTOR3* minSize, D3DXVECTOR3* maxSize, D3DXVECTOR3* rotRange )
where groupID is the foliage group you've loaded into the foliage pool, in this case I pass 'groupGrass' which contains about 10 types of items, 2 of which are used here(0 and 1). Also this above function is merely a helper function that automatically creates loads of instances of 'class FoliageTileShift' where each instance signifies a cell, if you need full control over how they are spawned and where then you can call its constructor manually and/or look at how this helper function does it. Foliage items are added to the foliage pool(think of it as a media library) like this:
// Grass
groupGrass = F_Pool::AddGroup();
{
// Load Foliage: Grass1
dbLoadObject( "Foliage\\Grass\\Visual.dbo", ++objectID );
F_Pool::AddLOD( groupGrass, 0.0, objectID, SHADER_diffuseSwayV, TEX_grass1, TEX_SHADOW_MAP, TEX_SHADOW_MASK );
F_Pool::SetLODFlags( false, 4, false );
// Load Foliage: Grass2
dbLoadObject( "Foliage\\Grass\\Visual.dbo", ++objectID );
F_Pool::AddLOD( groupGrass, 0.0, objectID, SHADER_diffuseSwayV, TEX_wildGrass1, TEX_SHADOW_MAP, TEX_SHADOW_MASK );
F_Pool::SetLODFlags( false, 4, false );
{... More stuff here, just trimmed it out...}
}
I'll explain it in more detail when I come to release the code but I think it's fairly easy to use.