Bladeren bron

Terrain: Fix texture disposes and loading optimizations

trethaller 6 jaren geleden
bovenliggende
commit
819b14f20c
2 gewijzigde bestanden met toevoegingen van 48 en 20 verwijderingen
  1. 10 0
      h3d/scene/pbr/terrain/Terrain.hx
  2. 38 20
      h3d/scene/pbr/terrain/Tile.hx

+ 10 - 0
h3d/scene/pbr/terrain/Terrain.hx

@@ -154,6 +154,16 @@ class Terrain extends Object {
 		refreshTex();
 	}
 
+	public function createEmptyTile(x : Int, y : Int) : Tile {
+		var tile = getTile(x,y);
+		if(tile == null){
+			tile = new Tile(x, y, this);
+			tile.refreshMesh();
+			tiles.push(tile);
+		}
+		return tile;
+	}
+
 	public function createTile( x : Int, y : Int ) : Tile {
 		var tile = getTile(x,y);
 		if( tile == null ) {

+ 38 - 20
h3d/scene/pbr/terrain/Tile.hx

@@ -33,10 +33,14 @@ class Tile extends h3d.scene.Mesh {
 	}
 
 	override function onRemove() {
-		if( heightMap != null ) heightMap.dispose();
-		if( surfaceIndexMap != null ) surfaceIndexMap.dispose();
+		if( heightMap != null )
+			heightMap.dispose();
+		if( surfaceIndexMap != null )
+			surfaceIndexMap.dispose();
 		for( i in 0 ... surfaceWeights.length )
 			if( surfaceWeights[i] != null ) surfaceWeights[i].dispose();
+		if( surfaceWeightArray != null )
+			surfaceWeightArray.dispose();
 	}
 
 	public override function clone( ?o : h3d.scene.Object ) : h3d.scene.Object {
@@ -113,10 +117,11 @@ class Tile extends h3d.scene.Mesh {
 		computeEdgesNormals();
 	}
 
-	public function refresh() {
+	function refreshHeightMap() {
 		if( heightMap == null || heightMap.width != getTerrain().heightMapResolution + 1 ) {
 			var oldHeightMap = heightMap;
 			heightMap = new h3d.mat.Texture(getTerrain().heightMapResolution + 1, getTerrain().heightMapResolution + 1, [Target], RGBA32F );
+			heightMap.name = "terrainHeightMap";
 			heightMap.wrap = Clamp;
 			heightMap.filter = Linear;
 			heightMap.preventAutoDispose();
@@ -127,10 +132,13 @@ class Tile extends h3d.scene.Mesh {
 			}
 			needNewPixelCapture = true;
 		}
+	}
 
+	function refreshIndexMap() {
 		if( surfaceIndexMap == null || surfaceIndexMap.width != getTerrain().weightMapResolution ) {
 			var oldSurfaceIndexMap = surfaceIndexMap;
 			surfaceIndexMap = new h3d.mat.Texture(getTerrain().weightMapResolution, getTerrain().weightMapResolution, [Target], RGBA);
+			surfaceIndexMap.name = "terrainSurfaceIndexMap";
 			surfaceIndexMap.filter = Nearest;
 			surfaceIndexMap.preventAutoDispose();
 			surfaceIndexMap.realloc = null;
@@ -139,30 +147,40 @@ class Tile extends h3d.scene.Mesh {
 				oldSurfaceIndexMap.dispose();
 			}
 		}
+	}
 
+	function refreshSurfaceWeights() {
 		if( getTerrain().surfaceArray.surfaceCount > 0 && (surfaceWeights.length != getTerrain().surfaceArray.surfaceCount || surfaceWeights[0].width != getTerrain().weightMapResolution) ) {
-			var oldArray = surfaceWeights;
-			surfaceWeights = new Array<h3d.mat.Texture>();
-			surfaceWeights = [for( i in 0...getTerrain().surfaceArray.surfaceCount ) null];
-			for( i in 0 ... surfaceWeights.length ) {
-				surfaceWeights[i] = new h3d.mat.Texture(getTerrain().weightMapResolution, getTerrain().weightMapResolution, [Target], R8);
-				surfaceWeights[i].wrap = Clamp;
-				surfaceWeights[i].preventAutoDispose();
-				surfaceWeights[i].realloc = null;
-				if( i < oldArray.length && oldArray[i] != null )
-					getTerrain().copyPass.apply(oldArray[i], surfaceWeights[i]);
-			}
-			generateWeightArray();
-
-			for( i in 0 ... oldArray.length )
-				if( oldArray[i] != null) oldArray[i].dispose();
+				var oldArray = surfaceWeights;
+				surfaceWeights = new Array<h3d.mat.Texture>();
+				surfaceWeights = [for( i in 0...getTerrain().surfaceArray.surfaceCount ) null];
+				for( i in 0 ... surfaceWeights.length ) {
+					surfaceWeights[i] = new h3d.mat.Texture(getTerrain().weightMapResolution, getTerrain().weightMapResolution, [Target], R8);
+					surfaceWeights[i].name = "terrainSurfaceWeight"+i;
+					surfaceWeights[i].wrap = Clamp;
+					surfaceWeights[i].preventAutoDispose();
+					surfaceWeights[i].realloc = null;
+					if( i < oldArray.length && oldArray[i] != null )
+						getTerrain().copyPass.apply(oldArray[i], surfaceWeights[i]);
+				}
+				for( t in oldArray )
+					if( t != null)
+						t.dispose();
 		}
 	}
 
+	public function refresh() {
+		refreshHeightMap();
+		refreshIndexMap();
+		refreshSurfaceWeights();
+		generateWeightArray();
+	}
+
 	public function generateWeightArray() {
 		if( surfaceWeightArray == null || surfaceWeightArray.width != getTerrain().weightMapResolution || surfaceWeightArray.get_layerCount() != surfaceWeights.length ) {
 			if( surfaceWeightArray != null ) surfaceWeightArray.dispose();
 			surfaceWeightArray = new h3d.mat.TextureArray(getTerrain().weightMapResolution, getTerrain().weightMapResolution, surfaceWeights.length, [Target], R8);
+			surfaceWeightArray.name = "terrainSurfaceWeightArray";
 			surfaceWeightArray.wrap = Clamp;
 			surfaceWeightArray.preventAutoDispose();
 			surfaceWeightArray.realloc = null;
@@ -580,11 +598,11 @@ class Tile extends h3d.scene.Mesh {
 				return false;
 
 			for( i in 0 ... surfaceWeights.length )
-				if( surfaceWeights[i] == null )
+				if( surfaceWeights[i] == null || surfaceWeights[i].isDisposed() )
 					return false;
 		}
 
-		if( heightMap == null )
+		if( heightMap == null || heightMap.isDisposed() )
 			return false;
 
 		return true;