Purpose: The purpose of this is to merge all of a landscapes splat textures in to a single cohesive texture, that is merged with the base texture map of your landscape. this will allow you to still in essence use splatting, without the fps hit; and also allow you to use detail textures on landscapes if your heart so desires.
Good luck,
almaris
P.S Thanks to Sylvain for all of your help with this. I realize that some of this is pretty specific to the way I do things, but it is commented pretty well so hopefully it won’t be too big of a challenge to figure out where I was going with things.
Public Sub MergeSplats() If MessageBox.Show("This function is not undoable and will remove all splats permanently, are you sure you wish to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) = DialogResult.Yes Then Dim scr As New TVScreen2DImmediate If Me.BaseTextureMap Is Nothing Then Exit Sub If Me.BaseTextureMap.Index = -1 Then Exit Sub With Context.TextureFactory 'base texturemap info struct Dim tinfo As TV_TEXTURE = .GetTextureInfo(Me.BaseTextureMap.Index) 'base texturemap size Dim tsize As New Size(tinfo.RealWidth, tinfo.RealHeight) 'tv_color structs Dim COLPIXELBASE As TV_COLOR Dim COLPIXELSPLAT As TV_COLOR Dim COLPIXELALPHA As TV_COLOR Dim FINALCOL As New TV_COLOR 'stores width/height ratios Dim walpha As Single Dim halpha As Single Dim wsplat As Single Dim hsplat As Single 'set up final texture rendersurface Dim finaltex As TVRenderSurface = Context.Scene.CreateRenderSurface(tsize.Width, tsize.Height, False, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_A8R8G8B8) 'draw base texture on rs finaltex.StartRender() scr.Draw_Texture(Me.BaseTextureMap.Index, 0, 0, tsize.Width, tsize.Height) finaltex.EndRender() 'create static texture from blank rs Dim ifinaltex As Integer = finaltex.CreateStaticTextureFromRenderSurface(tsize.Width, tsize.Height) 'stop landscape from rendering Me.Enabled = False For Each splat As Splat In Me.Splats If Not splat.BaseTexture Is Nothing Then If Not splat.BaseTexture.Index = -1 Then If Not splat.AlphaTexture Is Nothing Then 'splat texturemap info struct Dim splatinfo As TV_TEXTURE = .GetTextureInfo(splat.BaseTexture.Index) Dim isplatalphatex As Integer = splat.AlphaTexture.CreateStaticTextureFromRenderSurface(splat.AlphaSize.Width, splat.AlphaSize.Height) Dim isplattex As Integer = splat.BaseTexture.Index Dim colors As New ArrayList 'lock textures .LockTexture(ifinaltex) .LockTexture(isplattex) .LockTexture(isplatalphatex) 'set up ratios walpha = tsize.Width / splat.AlphaSize.Width halpha = tsize.Height / splat.AlphaSize.Height wsplat = tsize.Width / splatinfo.RealWidth hsplat = tsize.Height / splatinfo.RealHeight For y As Integer = 0 To tsize.Height - 1 For x As Integer = 0 To tsize.Width - 1 'decode base texture map pixel COLPIXELBASE = Context.Global.DecodeRGBA(.GetPixel(ifinaltex, x, y)) 'decode splat texture pixel with tiling, ratio, width, height and shift COLPIXELSPLAT = Context.Global.DecodeRGBA(.GetPixel(isplattex, _ (splat.ShiftU + (x / wsplat * splat.TileU)) Mod splatinfo.RealWidth, _ (splat.ShiftV + (y / hsplat * splat.TileV)) Mod splatinfo.RealHeight)) 'decode splat alpha pixel COLPIXELALPHA = Context.Global.DecodeRGBA(.GetPixel(isplatalphatex, x / walpha, y / halpha)) 'set pixel values FINALCOL.r = COLPIXELBASE.r * (1 - COLPIXELALPHA.a) + COLPIXELSPLAT.r * COLPIXELALPHA.a FINALCOL.g = COLPIXELBASE.g * (1 - COLPIXELALPHA.a) + COLPIXELSPLAT.g * COLPIXELALPHA.a FINALCOL.b = COLPIXELBASE.b * (1 - COLPIXELALPHA.a) + COLPIXELSPLAT.b * COLPIXELALPHA.a FINALCOL.a = 1 'add to colors arraylist colors.Add(Context.Global.RGBA(FINALCOL.r, FINALCOL.g, FINALCOL.b, FINALCOL.a)) Next Next 'unlock splat textures .UnlockTexture(isplatalphatex) .UnlockTexture(isplattex) 'write pixel array to destination image .SetPixelArray(ifinaltex, 0, 0, tsize.Width, tsize.Height, colors.ToArray(GetType(Int32))) End If End If End If Next 'post merge steps: (these will definately be different for you, but this is where you'll want to save the texture and do anything else to it) 'unlock final texture .UnlockTexture(ifinaltex) 'reenable landscape rendering Me.Enabled = True Dim texfile As String = Me.BaseTextureMap.Filename 'overwrites existing texture map Context.TextureFactory.SaveTexture(ifinaltex, texfile, CONST_TV_IMAGEFORMAT.TV_IMAGE_JPG) 'deletes from texfac and reloads the texture file Me.BaseTextureMap.RefreshTexture() 'remove all splat layers from landscape Me.Splats.DisposeAll() Me.Splats.Clear() 'recreate landscape Me.Recreate() 'delete splat files associated with this landscape For Each splatfile As String In _ System.IO.Directory.GetFiles(Util.StripFilenameFromPath( _ Util.StripExtensionAndDotFromPath(texfile))) If splatfile.ToLower.EndsWith(".splat") Then If System.IO.File.Exists(splatfile) Then System.IO.File.Delete(splatfile) End If End If Next End With End If End Sub