Here is some cool texture 2 grass code I made. I looked a long time for something like this on the forum but couldn't really find what i was looking for.
It's in VB6 so it's easy to translate and pretty self-explanatory.
You'll need the grass mesh (a plane will do), a minimesh object, and a 1024x1024 RGB texture. Just paint it more white where you want more grass to be. With this code you can also set a limit on minimesh count and it will still 'color' your landscape evenly with grass where it needs it. Kinda neat.
Some demo pictures attached.
Public Sub PlaceGrassTexture(GrassTexture As Long)
Dim minIslandVec As TV_3DVECTOR
Dim maxIslandVec As TV_3DVECTOR
Dim textureSize As Single
Dim maxMiniCount As Long
Dim VectorArrayX(1048576) As Single
Dim VectorArrayZ(1048576) As Single
Dim EveningRatio As Double
Dim HitCount As Long
maxMiniCount = 42000 'multiple of 3
textureSize = 1024
Island.GetBoundingBox minIslandVec, maxIslandVec ' your landscape
FlowerTexID = TVTextures.LoadTexture("grass2.dds")
GrassMatID = TVMaterials.CreateMaterial("Level1_2Material")
TVMaterials.SetAmbient GrassMatID, 0.8, 0.8, 0.8, 1
TVMaterials.SetDiffuse GrassMatID, 1, 1, 1, 1
TVMaterials.SetSpecular GrassMatID, 0, 0, 0, 1
TVMaterials.SetEmissive GrassMatID, 0, 0, 0, 1
TVMaterials.SetOpacity GrassMatID, 1
TVMaterials.SetPower GrassMatID, 0
Set GrassMesh1 = TVScene.CreateMeshBuilder("GrassMesh1")
GrassMesh1.LoadXFile "grass1.x"
GrassMesh1.SetTexture FlowerTexID
GrassMesh1.SetMaterial GrassMatID
GrassMesh1.SetBlendingMode TV_BLEND_ALPHA
GrassMesh1.SetAlphaTest True, , False
GrassMesh1.SetCullMode TV_DOUBLESIDED
GrassMesh1.EnableFrustumCulling True, True
GrassMesh1.SetScale 2, 2, 2
GrassMesh1.SetShadowCast False, False
Set Foliage(0) = TVScene.CreateMiniMesh(maxMiniCount, "grass1")
Foliage(0).CreateFromMesh GrassMesh1, True
Foliage(0).Enable True
Foliage(0).SetCullMode TV_DOUBLESIDED
Dim X1 As Long
Dim Y1 As Long
Dim TexVal1 As Long
Dim Red1 As Integer
Dim Green1 As Integer
Dim Blue1 As Integer
Dim LandToTextureRatio As Single
LandToTextureRatio = TVMath.GetDistance2D(minIslandVec.X, 0, maxIslandVec.X, 0) / textureSize
For X1 = 0 To textureSize - 1
For Y1 = 0 To textureSize - 1
TexVal1 = TVTextures.GetPixel(GrassTexture, X1, Y1)
Long2RGB TexVal1, Red1, Green1, Blue1 'Long to RGB function (look it up on Googly)
If Red1 < 5 Then rand1 = 0: GoTo done1
If Red1 < 25 Then rand1 = CreateRandNumber(1, 10): GoTo done1 ' Create a random number between 1 and 10
If Red1 < 50 Then rand1 = CreateRandNumber(2, 10): GoTo done1
If Red1 < 75 Then rand1 = CreateRandNumber(3, 10): GoTo done1
If Red1 < 100 Then rand1 = CreateRandNumber(4, 10): GoTo done1
If Red1 < 125 Then rand1 = CreateRandNumber(5, 10): GoTo done1
If Red1 < 150 Then rand1 = CreateRandNumber(6, 10): GoTo done1
If Red1 < 175 Then rand1 = CreateRandNumber(7, 10): GoTo done1
If Red1 < 200 Then rand1 = CreateRandNumber(8, 10): GoTo done1
If Red1 < 225 Then rand1 = CreateRandNumber(9, 10): GoTo done1
If Red1 < 255 Then rand1 = 10
done1:
If rand1 = 10 Then
VectorArrayX(HitCount) = minIslandVec.X + (X1 * LandToTextureRatio)
VectorArrayZ(HitCount) = minIslandVec.z + (Y1 * LandToTextureRatio)
HitCount = HitCount + 1
End If
Next Y1
Next X1
If HitCount > maxMiniCount / 3 Then
EveningRatio = HitCount / (maxMiniCount / 3)
Dim Integer1 As Long
Dim RandEven As Long
Integer1 = EveningRatio * 1000
For i = 0 To HitCount
RandEven = CreateRandNumber(1, Integer1)
If RandEven < 1000 - 1 Then
For u = 0 To 2
grassMiniCount = grassMiniCount + 1
Foliage(0).EnableMiniMesh grassMiniCount, True
Foliage(0).SetPosition VectorArrayX(i), Island.GetHeight(VectorArrayX(i), VectorArrayZ(i)), VectorArrayZ(i), grassMiniCount
If u = 0 Then Foliage(0).SetRotation 0, 0, 0, grassMiniCount
If u = 1 Then Foliage(0).SetRotation 0, 120, 0, grassMiniCount
If u = 2 Then Foliage(0).SetRotation 0, 240, 0, grassMiniCount
Next u
End If
Next i
Else
For i = 0 To HitCount / 3
For u = 0 To 2
grassMiniCount = grassMiniCount + 1
Foliage(0).EnableMiniMesh grassMiniCount, True
Foliage(0).SetPosition VectorArrayX(i), Island.GetHeight(VectorArrayX(i), VectorArrayZ(i)), VectorArrayZ(i), grassMiniCount
If i = 0 Then Foliage(0).SetRotation 0, 0, 0, grassMiniCount
If i = 1 Then Foliage(0).SetRotation 0, 120, 0, grassMiniCount
If i = 2 Then Foliage(0).SetRotation 0, 240, 0, grassMiniCount
Next u
Next i
End If
End Sub