浏览代码

some more minor fixes for cube textures

ncannasse 7 年之前
父节点
当前提交
b1ab679c0c
共有 3 个文件被更改,包括 51 次插入22 次删除
  1. 34 12
      h3d/Engine.hx
  2. 9 5
      h3d/impl/Serializable.hx
  3. 8 5
      h3d/mat/Texture.hx

+ 34 - 12
h3d/Engine.hx

@@ -4,9 +4,13 @@ import h3d.mat.Data;
 private class TargetTmp {
 	public var t : h3d.mat.Texture;
 	public var next : TargetTmp;
-	public function new(t, n) {
+	public var face : Int;
+	public var mipLevel : Int;
+	public function new(t, n, f, m) {
 		this.t = t;
 		this.next = n;
+		this.face = f;
+		this.mipLevel = m;
 	}
 }
 
@@ -40,7 +44,9 @@ class Engine {
 
 	var targetTmp : TargetTmp;
 	var targetStack : TargetTmp;
-	var currentTarget : h3d.mat.Texture;
+	var currentTargetTex : h3d.mat.Texture;
+	var currentTargetFace : Int;
+	var currentTargetMip : Int;
 	var needFlushTarget : Bool;
 	var nullTexture : h3d.mat.Texture;
 	var textureColorCache = new Map<Int,h3d.mat.Texture>();
@@ -261,7 +267,7 @@ class Engine {
 		shaderSwitches = 0;
 		drawCalls = 0;
 		targetStack = null;
-		needFlushTarget = currentTarget != null;
+		needFlushTarget = currentTargetTex != null;
 		driver.begin(frameCount);
 		if( backgroundColor != null ) clear(backgroundColor, 1, 0);
 		return true;
@@ -279,24 +285,34 @@ class Engine {
 		return targetStack == null ? null : targetStack.t;
 	}
 
-	public function pushTarget( tex : h3d.mat.Texture ) {
+	public function pushTarget( tex : h3d.mat.Texture, face = 0, mipLevel = 0 ) {
 		var c = targetTmp;
 		if( c == null )
-			c = new TargetTmp(tex, targetStack);
+			c = new TargetTmp(tex, targetStack, face, mipLevel);
 		else {
 			targetTmp = c.next;
 			c.t = tex;
 			c.next = targetStack;
+			c.mipLevel = mipLevel;
+			c.face = face;
 		}
 		targetStack = c;
-		needFlushTarget = currentTarget != tex;
+		updateNeedFlush();
+	}
+
+	function updateNeedFlush() {
+		var t = targetStack;
+		if( t == null )
+			needFlushTarget = currentTargetTex != null;
+		else
+			needFlushTarget = currentTargetTex != t.t || currentTargetFace != t.face || currentTargetMip != t.mipLevel;
 	}
 
 	public function pushTargets( textures : Array<h3d.mat.Texture> ) {
 		if( nullTexture == null ) nullTexture = new h3d.mat.Texture(0, 0, [NoAlloc]);
 		pushTarget(nullTexture);
 		driver.setRenderTargets(textures);
-		currentTarget = nullTexture;
+		currentTargetTex = nullTexture;
 		needFlushTarget = false;
 	}
 
@@ -305,8 +321,7 @@ class Engine {
 		if( c == null )
 			throw "popTarget() with no matching pushTarget()";
 		targetStack = c.next;
-		var tex = targetStack == null ? null : targetStack.t;
-		needFlushTarget = currentTarget != tex;
+		updateNeedFlush();
 		// recycle
 		c.t = null;
 		c.next = targetTmp;
@@ -318,9 +333,16 @@ class Engine {
 	}
 
 	function doFlushTarget() {
-		var tex = targetStack == null ? null : targetStack.t;
-		currentTarget = tex;
-		driver.setRenderTarget(tex);
+		var t = targetStack;
+		if( t == null ) {
+			driver.setRenderTarget(null);
+			currentTargetTex = null;
+		} else {
+			driver.setRenderTarget(t.t, t.face, t.mipLevel);
+			currentTargetTex = t.t;
+			currentTargetFace = t.face;
+			currentTargetMip = t.mipLevel;
+		}
 		needFlushTarget = false;
 	}
 

+ 9 - 5
h3d/impl/Serializable.hx

@@ -41,14 +41,17 @@ class SceneSerializer extends hxbit.Serializer {
 		}
 		if( t.flags.has(Serialize) ) {
 			addInt(2);
-			var pix = t.capturePixels();
-			pix.convert(texOutputFormat);
 			addInt(t.width);
 			addInt(t.height);
 			addInt(t.flags.toInt());
 			addInt(t.format.getIndex());
-			addInt(pix.format.getIndex());
-			addBytesSub(pix.bytes, 0, t.width * t.height * hxd.Pixels.bytesPerPixel(pix.format));
+			var fmt = texOutputFormat;
+			addInt(fmt.getIndex());
+			for( face in 0...(t.flags.has(Cube) ? 6 : 1) ) {
+				var pix = t.capturePixels(face);
+				pix.convert(fmt);
+				addBytesSub(pix.bytes, 0, t.width * t.height * hxd.Pixels.bytesPerPixel(pix.format));
+			}
 			return true;
 		}
 		var tch = Std.instance(t, h3d.mat.TextureChannels);
@@ -97,7 +100,8 @@ class SceneSerializer extends hxbit.Serializer {
 			if( kind == 2 ) {
 				var pixFormat = h3d.mat.Data.TextureFormat.createByIndex(getInt());
 				t = new h3d.mat.Texture(width, height, flags, format);
-				t.uploadPixels(new hxd.Pixels(width, height, getBytes(), pixFormat));
+				for( face in 0...(t.flags.has(Cube)?6:1) )
+					t.uploadPixels(new hxd.Pixels(width, height, getBytes(), pixFormat), 0, face);
 			} else {
 				var ct = new h3d.mat.TextureChannels(width, height, flags, format);
 				ct.allowAsync = false;

+ 8 - 5
h3d/mat/Texture.hx

@@ -257,9 +257,12 @@ class Texture {
 		Downloads the current texture data from the GPU.
 		Beware, this is a very slow operation that shouldn't be done during rendering.
 	**/
-	public function capturePixels() {
+	public function capturePixels( face = 0, mipLevel = 0 ) {
 		#if flash
 
+		if( face != 0 || mipLevel != 0 )
+			throw "Can't capture face/mipLevel";
+
 		var twoPassCapture = true;
 
 		var e = h3d.Engine.getCurrent();
@@ -315,7 +318,7 @@ class Texture {
 		#else
 
 		var e = h3d.Engine.getCurrent();
-		e.pushTarget(this);
+		e.pushTarget(this, face, mipLevel);
 		@:privateAccess e.flushTarget();
 		var pixels = hxd.Pixels.alloc(width, height, RGBA);
 		e.driver.captureRenderBuffer(pixels);
@@ -382,12 +385,12 @@ class Texture {
 	**/
 	public static function defaultCubeTexture() {
 		var engine = h3d.Engine.getCurrent();
-		var t = @:privateAccess engine.resCache.get(Texture);
+		var t : h3d.mat.Texture = @:privateAccess engine.resCache.get(Texture);
 		if( t != null )
 			return t;
 		t = new Texture(1, 1, [Cube]);
-		t.clear(0);
-		t.realloc = function() t.clear(0);
+		t.clear(0x202020);
+		t.realloc = function() t.clear(0x202020);
 		@:privateAccess engine.resCache.set(Texture,t);
 		return t;
 	}