Sfoglia il codice sorgente

added Texture.mipLevels, fixed a few mip level handling for not squared texture

Nicolas Cannasse 4 anni fa
parent
commit
83192fb613
3 ha cambiato i file con 44 aggiunte e 17 eliminazioni
  1. 20 11
      h3d/impl/DirectXDriver.hx
  2. 13 6
      h3d/impl/GlDriver.hx
  3. 11 0
      h3d/mat/Texture.hx

+ 20 - 11
h3d/impl/DirectXDriver.hx

@@ -381,9 +381,8 @@ class DirectXDriver extends h3d.impl.Driver {
 	override function allocTexture(t:h3d.mat.Texture):Texture {
 
 		var mips = 1;
-		if( t.flags.has(MipMapped) ) {
-			while( t.width >= 1 << mips || t.height >= 1 << mips ) mips++;
-		}
+		if( t.flags.has(MipMapped) )
+			mips = t.mipLevels;
 
 		var rt = t.flags.has(Target);
 		var isCube = t.flags.has(Cube);
@@ -522,10 +521,18 @@ class DirectXDriver extends h3d.impl.Driver {
 			if (region.yMax > tex.height) region.yMax = tex.height;
 			if (region.xMin < 0) region.xMin = 0;
 			if (region.yMin < 0) region.yMin = 0;
-			pixels = hxd.Pixels.alloc(region.width >> mipLevel, region.height >> mipLevel, tex.format);
+			var w = region.width >> mipLevel;
+			var h = region.height >> mipLevel;
+			if( w == 0 ) w = 1;
+			if( h == 0 ) h = 1;
+			pixels = hxd.Pixels.alloc(w, h, tex.format);
 			captureTexPixels(pixels, tex, layer, mipLevel, region.xMin, region.yMin);
 		} else {
-			pixels = hxd.Pixels.alloc(tex.width >> mipLevel, tex.height >> mipLevel, tex.format);
+			var w = tex.width >> mipLevel;
+			var h = tex.height >> mipLevel;
+			if( w == 0 ) w = 1;
+			if( h == 0 ) h = 1;
+			pixels = hxd.Pixels.alloc(w, h, tex.format);
 			captureTexPixels(pixels, tex, layer, mipLevel);
 		}
 		return pixels;
@@ -562,16 +569,16 @@ class DirectXDriver extends h3d.impl.Driver {
 		}
 
 		var pitch = 0;
-		var bpp = hxd.Pixels.calcStride(1, tex.format);
+		var stride = hxd.Pixels.calcStride(desc.width, tex.format);
 		var ptr = tmp.map(0, Read, true, pitch);
 
 		if( hasDeviceError ) throw "Device was disposed during capturePixels";
 
-		if( pitch == desc.width * bpp )
-			@:privateAccess pixels.bytes.b.blit(0, ptr, 0, desc.width * desc.height * bpp);
+		if( pitch == stride )
+			@:privateAccess pixels.bytes.b.blit(0, ptr, 0, desc.height * stride);
 		else {
 			for( i in 0...desc.height )
-				@:privateAccess pixels.bytes.b.blit(i * desc.width * bpp, ptr, i * pitch, desc.width * bpp);
+				@:privateAccess pixels.bytes.b.blit(i * stride, ptr, i * pitch, stride);
 		}
 		tmp.unmap(0);
 		tmp.release();
@@ -877,8 +884,10 @@ class DirectXDriver extends h3d.impl.Driver {
 		Driver.omSetRenderTargets(textures.length, currentTargets, currentDepth == null ? null : currentDepth.view);
 		targetsCount = textures.length;
 
-		viewport[2] = tex.width >> mipLevel;
-		viewport[3] = tex.height >> mipLevel;
+		var w = tex.width >> mipLevel; if( w == 0 ) w = 1;
+		var h = tex.height >> mipLevel; if( h == 0 ) h = 1;
+		viewport[2] = w;
+		viewport[3] = h;
 		viewport[5] = 1.;
 		Driver.rsSetViewports(1, viewport);
 	}

+ 13 - 6
h3d/impl/GlDriver.hx

@@ -1425,23 +1425,28 @@ class GlDriver extends Driver {
 	override function capturePixels(tex:h3d.mat.Texture, layer:Int, mipLevel:Int, ?region:h2d.col.IBounds) {
 
 		var pixels : hxd.Pixels;
-		var x : Int, y : Int;
+		var x : Int, y : Int, w : Int, h : Int;
 		if (region != null) {
 			if (region.xMax > tex.width) region.xMax = tex.width;
 			if (region.yMax > tex.height) region.yMax = tex.height;
 			if (region.xMin < 0) region.xMin = 0;
 			if (region.yMin < 0) region.yMin = 0;
-			pixels = hxd.Pixels.alloc(region.width >> mipLevel, region.height >> mipLevel, tex.format);
+			w = region.width;
+			h = region.height;
 			x = region.xMin;
 			y = region.yMin;
 		} else {
-			pixels = hxd.Pixels.alloc(tex.width >> mipLevel, tex.height >> mipLevel, tex.format);
+			w = tex.width;
+			h = tex.height;
 			x = 0;
 			y = 0;
 		}
 
-		if( pixels.width == 0 || pixels.height == 0 )
-			return pixels;
+		w >>= mipLevel;
+		h >>= mipLevel;
+		if( w == 0 ) w = 1;
+		if( h == 0 ) h = 1;
+		pixels = hxd.Pixels.alloc(w, h, tex.format);
 
 		var old = curTarget;
 		var oldCount = numTargets;
@@ -1519,7 +1524,9 @@ class GlDriver extends Driver {
 			gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.STENCIL_ATTACHMENT, GL.RENDERBUFFER, null);
 		}
 
-		gl.viewport(0, 0, tex.width >> mipLevel, tex.height >> mipLevel);
+		var w = tex.width >> mipLevel; if( w == 0 ) w = 1;
+		var h = tex.height >> mipLevel; if( h == 0 ) h = 1;
+		gl.viewport(0, 0, w, h);
 		for( i in 0...boundTextures.length )
 			boundTextures[i] = null;
 

+ 11 - 0
h3d/mat/Texture.hx

@@ -39,6 +39,7 @@ class Texture {
 	public var wrap(default, set) : Wrap;
 	public var layerCount(get, never) : Int;
 	public var lodBias : Float = 0.;
+	public var mipLevels(get, never) : Int;
 
 	/**
 		If this callback is set, the texture can be re-allocated when the 3D context has been lost or when
@@ -67,6 +68,16 @@ class Texture {
 		return _lastFrame;
 	}
 
+	function get_mipLevels() {
+		if( !flags.has(MipMapped) )
+			return 1;
+		/* atm we don't allow textures with mipmaps < max levels */
+		var lv = 1;
+		var w = width, h = height;
+		while( (w >> lv) >= 1 || (h >> lv) >= 1 ) lv++;
+		return lv;
+	}
+
 	public function new(w, h, ?flags : Array<TextureFlags>, ?format : TextureFormat ) {
 		#if !noEngine
 		var engine = h3d.Engine.getCurrent();