internal TerrainPatch( HeightMap heightMap, Rectangle patchBounds, GraphicsDevice graphicsDevice, TerrainPatchIndexBufferCache indexBufferCache, ResourceSet materialResourceSet) { Bounds = patchBounds; _indexBuffer = indexBufferCache.GetIndexBuffer( patchBounds.Width, patchBounds.Height, out var indices); _numIndices = (uint)indices.Length; _vertexBuffer = AddDisposable(CreateVertexBuffer( graphicsDevice, heightMap, patchBounds, indices, out var boundingBox, out var triangles)); BoundingBox = boundingBox; Triangles = triangles; _beforeRender = (cl, context) => { cl.SetGraphicsResourceSet(4, materialResourceSet); cl.SetVertexBuffer(0, _vertexBuffer); }; }
internal TerrainPatch( HeightMap heightMap, Rectangle patchBounds, GraphicsDevice graphicsDevice, TerrainPatchIndexBufferCache indexBufferCache, Material material) { Bounds = patchBounds; _indexBuffer = indexBufferCache.GetIndexBuffer( patchBounds.Width, patchBounds.Height, out var indices); _numIndices = (uint)indices.Length; _vertexBuffer = AddDisposable(CreateVertexBuffer( graphicsDevice, heightMap, patchBounds, indices, out var boundingBox, out var triangles)); BoundingBox = boundingBox; Triangles = triangles; _material = material; _beforeRender = (CommandList cl, Graphics.Rendering.RenderContext context, in RenderItem renderItem) => { cl.SetVertexBuffer(0, _vertexBuffer); }; }
internal TerrainPatch( HeightMap heightMap, Rectangle patchBounds, GraphicsDevice graphicsDevice, TerrainPatchIndexBufferCache indexBufferCache, Material material) { DebugName = $"Terrain_{Bounds}"; Bounds = patchBounds; _indexBuffer = indexBufferCache.GetIndexBuffer( patchBounds.Width, patchBounds.Height, out var indices); _numIndices = (uint)indices.Length; _vertexBuffer = AddDisposable(CreateVertexBuffer( graphicsDevice, heightMap, patchBounds, indices, out var boundingBox, out var triangles)); BoundingBox = boundingBox; Triangles = triangles; MaterialPass = new MaterialPass(material, null); }
private List <TerrainPatch> CreatePatches( GraphicsDevice graphicsDevice, HeightMap heightMap, TerrainPatchIndexBufferCache indexBufferCache, ResourceSet materialResourceSet, ResourceSet radiusCursorDecalsResourceSet, Func <ResourceSet> causticsRendererCallback) { const int numTilesPerPatch = PatchSize - 1; var heightMapWidthMinusOne = heightMap.Width - 1; var numPatchesX = heightMapWidthMinusOne / numTilesPerPatch; if (heightMapWidthMinusOne % numTilesPerPatch != 0) { numPatchesX += 1; } var heightMapHeightMinusOne = heightMap.Height - 1; var numPatchesY = heightMapHeightMinusOne / numTilesPerPatch; if (heightMapHeightMinusOne % numTilesPerPatch != 0) { numPatchesY += 1; } var patches = new List <TerrainPatch>(); for (var y = 0; y < numPatchesY; y++) { for (var x = 0; x < numPatchesX; x++) { var patchX = x * numTilesPerPatch; var patchY = y * numTilesPerPatch; var patchBounds = new Rectangle( patchX, patchY, Math.Min(PatchSize, heightMap.Width - patchX), Math.Min(PatchSize, heightMap.Height - patchY)); patches.Add(AddDisposable(new TerrainPatch( heightMap, patchBounds, graphicsDevice, indexBufferCache, materialResourceSet, radiusCursorDecalsResourceSet, causticsRendererCallback))); } } return(patches); }
internal TerrainPatch( HeightMap heightMap, Rectangle patchBounds, GraphicsDevice graphicsDevice, TerrainPatchIndexBufferCache indexBufferCache, ResourceSet materialResourceSet, ResourceSet radiusCursorDecalsResourceSet, Func <ResourceSet> causticsRendererCallback) { Bounds = patchBounds; _indexBuffer = indexBufferCache.GetIndexBuffer( patchBounds.Width, patchBounds.Height, out var indices); _numIndices = (uint)indices.Length; _vertexBuffer = AddDisposable(CreateVertexBuffer( graphicsDevice, heightMap, patchBounds, indices, out var boundingBox, out var triangles)); BoundingBox = boundingBox; Triangles = triangles; _beforeRender = (cl, context) => { var isRender = context.Scene3D.Waters.IsRenderCaustics; if (isRender) { var causticsResourceSet = causticsRendererCallback.Invoke(); cl.SetGraphicsResourceSet(4, causticsResourceSet); } else { cl.SetGraphicsResourceSet(4, materialResourceSet); } cl.SetGraphicsResourceSet(5, radiusCursorDecalsResourceSet); cl.SetVertexBuffer(0, _vertexBuffer); }; }
internal Terrain(MapFile mapFile, AssetLoadContext loadContext) { Map = mapFile; HeightMap = new HeightMap(mapFile.HeightMapData); _loadContext = loadContext; _graphicsDevice = loadContext.GraphicsDevice; _indexBufferCache = AddDisposable(new TerrainPatchIndexBufferCache(loadContext.GraphicsDevice)); var tileDataTexture = AddDisposable(CreateTileDataTexture( loadContext.GraphicsDevice, mapFile, HeightMap)); var cliffDetailsBuffer = AddDisposable(CreateCliffDetails( loadContext.GraphicsDevice, mapFile)); CreateTextures( loadContext, mapFile.BlendTileData, out var textureArray, out var textureDetails); var textureDetailsBuffer = AddDisposable(loadContext.GraphicsDevice.CreateStaticStructuredBuffer(textureDetails)); var terrainPipeline = loadContext.ShaderResources.Terrain.Pipeline; _materialConstantsBuffer = AddDisposable( new ConstantBuffer <TerrainShaderResources.TerrainMaterialConstants>( loadContext.GraphicsDevice, "TerrainMaterialConstants")); _materialConstantsBuffer.Value = new TerrainShaderResources.TerrainMaterialConstants { MapBorderWidth = new Vector2(mapFile.HeightMapData.BorderWidth, mapFile.HeightMapData.BorderWidth) * HeightMap.HorizontalScale, MapSize = new Vector2(mapFile.HeightMapData.Width, mapFile.HeightMapData.Height) * HeightMap.HorizontalScale, IsMacroTextureStretched = mapFile.EnvironmentData?.IsMacroTextureStretched ?? false }; _materialConstantsBuffer.Update(loadContext.GraphicsDevice); var macroTexture = loadContext.AssetStore.Textures.GetByName(mapFile.EnvironmentData?.MacroTexture ?? "tsnoiseurb.dds"); var casuticsTextures = BuildCausticsTextureArray(loadContext.AssetStore); var materialResourceSet = AddDisposable(loadContext.ShaderResources.Terrain.CreateMaterialResourceSet( _materialConstantsBuffer.Buffer, tileDataTexture, cliffDetailsBuffer ?? loadContext.StandardGraphicsResources.GetNullStructuredBuffer(TerrainShaderResources.CliffInfo.Size), textureDetailsBuffer, textureArray, macroTexture, casuticsTextures)); _material = AddDisposable( new Material( loadContext.ShaderResources.Terrain, loadContext.ShaderResources.Terrain.Pipeline, materialResourceSet)); CloudTexture = loadContext.AssetStore.Textures.GetByName(mapFile.EnvironmentData?.CloudTexture ?? "tscloudmed.dds"); OnHeightMapChanged(); }
internal Terrain(MapFile mapFile, AssetLoadContext loadContext) { Map = mapFile; HeightMap = new HeightMap(mapFile.HeightMapData); _graphicsDevice = loadContext.GraphicsDevice; _indexBufferCache = AddDisposable(new TerrainPatchIndexBufferCache(loadContext.GraphicsDevice)); var tileDataTexture = AddDisposable(CreateTileDataTexture( loadContext.GraphicsDevice, mapFile, HeightMap)); var cliffDetailsBuffer = AddDisposable(CreateCliffDetails( loadContext.GraphicsDevice, mapFile)); CreateTextures( loadContext, mapFile.BlendTileData, out var textureArray, out var textureDetails); var textureDetailsBuffer = AddDisposable(loadContext.GraphicsDevice.CreateStaticStructuredBuffer(textureDetails)); var terrainPipeline = loadContext.ShaderResources.Terrain.Pipeline; _materialConstantsBuffer = AddDisposable( new ConstantBuffer <TerrainShaderResources.TerrainMaterialConstants>( loadContext.GraphicsDevice, "TerrainMaterialConstants")); _materialConstantsBuffer.Value = new TerrainShaderResources.TerrainMaterialConstants { MapBorderWidth = new Vector2(mapFile.HeightMapData.BorderWidth, mapFile.HeightMapData.BorderWidth) * HeightMap.HorizontalScale, MapSize = new Vector2(mapFile.HeightMapData.Width, mapFile.HeightMapData.Height) * HeightMap.HorizontalScale, IsMacroTextureStretched = mapFile.EnvironmentData?.IsMacroTextureStretched ?? false }; _materialConstantsBuffer.Update(loadContext.GraphicsDevice); var macroTexture = loadContext.AssetStore.Textures.GetByName(mapFile.EnvironmentData?.MacroTexture ?? "tsnoiseurb.dds"); RadiusCursorDecals = AddDisposable(new RadiusCursorDecals(loadContext.AssetStore, loadContext.GraphicsDevice)); var casuticsTextures = BuildCausticsTextureArray(loadContext.AssetStore); _materialResourceSet = AddDisposable(loadContext.ShaderResources.Terrain.CreateMaterialResourceSet( _materialConstantsBuffer.Buffer, tileDataTexture, cliffDetailsBuffer ?? loadContext.StandardGraphicsResources.GetNullStructuredBuffer(TerrainShaderResources.CliffInfo.Size), textureDetailsBuffer, textureArray, macroTexture, casuticsTextures)); RadiusCursorDecalsResourceSet = AddDisposable(loadContext.ShaderResources.RadiusCursor.CreateRadiusCursorDecalsResourceSet( RadiusCursorDecals.TextureArray, RadiusCursorDecals.DecalConstants, RadiusCursorDecals.DecalsBuffer)); var cloudTexture = loadContext.AssetStore.Textures.GetByName(mapFile.EnvironmentData?.CloudTexture ?? "tscloudmed.dds"); var cloudResourceLayout = AddDisposable(loadContext.GraphicsDevice.ResourceFactory.CreateResourceLayout( new ResourceLayoutDescription( new ResourceLayoutElementDescription("Global_CloudTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment)))); CloudResourceSet = AddDisposable(loadContext.GraphicsDevice.ResourceFactory.CreateResourceSet( new ResourceSetDescription( cloudResourceLayout, cloudTexture.Texture))); CloudResourceSet.Name = "Cloud resource set"; _shaderSet = loadContext.ShaderResources.Terrain.ShaderSet; _pipeline = terrainPipeline; OnHeightMapChanged(); }