Sfoglia il codice sorgente

Adding 3D texture support on Opengl and WebGl.

clementlandrin 11 mesi fa
parent
commit
05a5764662
5 ha cambiato i file con 63 aggiunte e 11 eliminazioni
  1. 21 9
      h3d/impl/GlDriver.hx
  2. 4 0
      h3d/mat/Data.hx
  3. 5 1
      h3d/mat/Texture.hx
  4. 32 0
      h3d/mat/Texture3D.hx
  5. 1 1
      hxsl/GlslOut.hx

+ 21 - 9
h3d/impl/GlDriver.hx

@@ -1000,6 +1000,8 @@ class GlDriver extends Driver {
 	}
 	}
 
 
 	function getBindType( t : h3d.mat.Texture ) {
 	function getBindType( t : h3d.mat.Texture ) {
+		if ( t.flags.has(Is3D) )
+			return GL.TEXTURE_3D;
 		var isArray = t.flags.has(IsArray);
 		var isArray = t.flags.has(IsArray);
 		if( t.flags.has(Cube) )
 		if( t.flags.has(Cube) )
 			return #if (hlsdl > version("1.15.0")) isArray ? GL.TEXTURE_CUBE_MAP_ARRAY : #end GL.TEXTURE_CUBE_MAP;
 			return #if (hlsdl > version("1.15.0")) isArray ? GL.TEXTURE_CUBE_MAP_ARRAY : #end GL.TEXTURE_CUBE_MAP;
@@ -1117,7 +1119,7 @@ class GlDriver extends Driver {
 
 
 		// Patch RGBA to be RGBA8 because texStorage expect a "Sized Internal Format"
 		// Patch RGBA to be RGBA8 because texStorage expect a "Sized Internal Format"
 		var sizedFormat = tt.internalFmt == GL.RGBA ? GL.RGBA8 : tt.internalFmt;
 		var sizedFormat = tt.internalFmt == GL.RGBA ? GL.RGBA8 : tt.internalFmt;
-		if( t.flags.has(IsArray) && !t.flags.has(Cube) ) {
+		if( ( t.flags.has(IsArray) || t.flags.has(Is3D) ) && !t.flags.has(Cube) ) {
 			gl.texStorage3D(bind, t.mipLevels, sizedFormat, tt.width, tt.height, t.layerCount);
 			gl.texStorage3D(bind, t.mipLevels, sizedFormat, tt.width, tt.height, t.layerCount);
 			checkError();
 			checkError();
 		} else {
 		} else {
@@ -1128,6 +1130,7 @@ class GlDriver extends Driver {
 		for(mip in 0...t.mipLevels) {
 		for(mip in 0...t.mipLevels) {
 			var w = hxd.Math.imax(1, tt.width >> mip);
 			var w = hxd.Math.imax(1, tt.width >> mip);
 			var h = hxd.Math.imax(1, tt.height >> mip);
 			var h = hxd.Math.imax(1, tt.height >> mip);
+			var d = hxd.Math.imax(1, t.layerCount >> mip);
 			if( t.flags.has(Cube) ) {
 			if( t.flags.has(Cube) ) {
 				for( i in 0...6 ) {
 				for( i in 0...6 ) {
 					gl.texImage2D(CUBE_FACES[i], mip, tt.internalFmt, w, h, 0, getChannels(tt), tt.pixelFmt, null);
 					gl.texImage2D(CUBE_FACES[i], mip, tt.internalFmt, w, h, 0, getChannels(tt), tt.pixelFmt, null);
@@ -1136,6 +1139,9 @@ class GlDriver extends Driver {
 			} else if( t.flags.has(IsArray) ) {
 			} else if( t.flags.has(IsArray) ) {
 				gl.texImage3D(bind, mip, tt.internalFmt, w, h, t.layerCount, 0, getChannels(tt), tt.pixelFmt, null);
 				gl.texImage3D(bind, mip, tt.internalFmt, w, h, t.layerCount, 0, getChannels(tt), tt.pixelFmt, null);
 				checkError();
 				checkError();
+			} else if ( t.flags.has(Is3D) ) {
+				gl.texImage3D(bind, mip, tt.internalFmt, w, h, d, 0, getChannels(tt), tt.pixelFmt, null);
+				checkError();
 			} else {
 			} else {
 				gl.texImage2D(bind, mip, tt.internalFmt, w, h, 0, getChannels(tt), tt.pixelFmt, null);
 				gl.texImage2D(bind, mip, tt.internalFmt, w, h, 0, getChannels(tt), tt.pixelFmt, null);
 				checkError();
 				checkError();
@@ -1272,11 +1278,11 @@ class GlDriver extends Driver {
 	}
 	}
 
 
 	override function uploadTextureBitmap( t : h3d.mat.Texture, bmp : hxd.BitmapData, mipLevel : Int, side : Int ) {
 	override function uploadTextureBitmap( t : h3d.mat.Texture, bmp : hxd.BitmapData, mipLevel : Int, side : Int ) {
-	#if hl
+		#if hl
 		var pixels = bmp.getPixels();
 		var pixels = bmp.getPixels();
 		uploadTexturePixels(t, pixels, mipLevel, side);
 		uploadTexturePixels(t, pixels, mipLevel, side);
 		pixels.dispose();
 		pixels.dispose();
-	#else
+		#else
 		if( t.format != RGBA || t.layerCount != 1 ) {
 		if( t.format != RGBA || t.layerCount != 1 ) {
 			var pixels = bmp.getPixels();
 			var pixels = bmp.getPixels();
 			uploadTexturePixels(t, pixels, mipLevel, side);
 			uploadTexturePixels(t, pixels, mipLevel, side);
@@ -1287,7 +1293,7 @@ class GlDriver extends Driver {
 			gl.texSubImage2D(GL.TEXTURE_2D, mipLevel, 0, 0, getChannels(t.t), t.t.pixelFmt, img.getImageData(0, 0, bmp.width, bmp.height));
 			gl.texSubImage2D(GL.TEXTURE_2D, mipLevel, 0, 0, getChannels(t.t), t.t.pixelFmt, img.getImageData(0, 0, bmp.width, bmp.height));
 			restoreBind();
 			restoreBind();
 		}
 		}
-	#end
+		#end
 	}
 	}
 
 
 	/*
 	/*
@@ -1350,7 +1356,13 @@ class GlDriver extends Driver {
 
 
 	override function uploadTexturePixels( t : h3d.mat.Texture, pixels : hxd.Pixels, mipLevel : Int, side : Int ) {
 	override function uploadTexturePixels( t : h3d.mat.Texture, pixels : hxd.Pixels, mipLevel : Int, side : Int ) {
 		var cubic = t.flags.has(Cube);
 		var cubic = t.flags.has(Cube);
-		var face = cubic ? CUBE_FACES[side] : t.flags.has(IsArray) ? GL.TEXTURE_2D_ARRAY : GL.TEXTURE_2D;
+		var face = GL.TEXTURE_2D;
+		if ( cubic )
+			face = CUBE_FACES[side];
+		if ( t.flags.has(IsArray) )
+			face = GL.TEXTURE_2D_ARRAY
+		else if ( t.flags.has(Is3D) )
+			face = GL.TEXTURE_3D;
 		var bind = getBindType(t);
 		var bind = getBindType(t);
 		gl.bindTexture(bind, t.t.t);
 		gl.bindTexture(bind, t.t.t);
 		pixels.convert(t.format);
 		pixels.convert(t.format);
@@ -1358,14 +1370,14 @@ class GlDriver extends Driver {
 		#if hl
 		#if hl
 		var stream = streamData(pixels.bytes.getData(),pixels.offset,dataLen);
 		var stream = streamData(pixels.bytes.getData(),pixels.offset,dataLen);
 		if( t.format.match(S3TC(_)) ) {
 		if( t.format.match(S3TC(_)) ) {
-			if( t.flags.has(IsArray) )
+			if( t.flags.has(IsArray) || t.flags.has(Is3D) )
 				#if (hlsdl >= version("1.12.0"))
 				#if (hlsdl >= version("1.12.0"))
 				gl.compressedTexSubImage3D(face, mipLevel, 0, 0, side, pixels.width, pixels.height, 1, t.t.internalFmt, dataLen, stream);
 				gl.compressedTexSubImage3D(face, mipLevel, 0, 0, side, pixels.width, pixels.height, 1, t.t.internalFmt, dataLen, stream);
 				#else throw "TextureArray support requires hlsdl 1.12+"; #end
 				#else throw "TextureArray support requires hlsdl 1.12+"; #end
 			else
 			else
 				gl.compressedTexImage2D(face, mipLevel, t.t.internalFmt, pixels.width, pixels.height, 0, dataLen, stream);
 				gl.compressedTexImage2D(face, mipLevel, t.t.internalFmt, pixels.width, pixels.height, 0, dataLen, stream);
 		} else {
 		} else {
-			if( t.flags.has(IsArray) )
+			if( t.flags.has(IsArray) || t.flags.has(Is3D) )
 				#if (hlsdl >= version("1.12.0"))
 				#if (hlsdl >= version("1.12.0"))
 				gl.texSubImage3D(face, mipLevel, 0, 0, side, pixels.width, pixels.height, 1, getChannels(t.t), t.t.pixelFmt, stream);
 				gl.texSubImage3D(face, mipLevel, 0, 0, side, pixels.width, pixels.height, 1, getChannels(t.t), t.t.pixelFmt, stream);
 				#else throw "TextureArray support requires hlsdl 1.12+"; #end
 				#else throw "TextureArray support requires hlsdl 1.12+"; #end
@@ -1388,12 +1400,12 @@ class GlDriver extends Driver {
 		default: new Uint8Array(@:privateAccess pixels.bytes.b.buffer, pixels.offset, dataLen);
 		default: new Uint8Array(@:privateAccess pixels.bytes.b.buffer, pixels.offset, dataLen);
 		}
 		}
 		if( t.format.match(S3TC(_)) ) {
 		if( t.format.match(S3TC(_)) ) {
-			if( t.flags.has(IsArray) )
+			if( t.flags.has(IsArray) || t.flags.has(Is3D) )
 				gl.compressedTexSubImage3D(face, mipLevel, 0, 0, side, pixels.width, pixels.height, 1, t.t.internalFmt, buffer);
 				gl.compressedTexSubImage3D(face, mipLevel, 0, 0, side, pixels.width, pixels.height, 1, t.t.internalFmt, buffer);
 			else
 			else
 				gl.compressedTexSubImage2D(face, mipLevel, 0, 0, pixels.width, pixels.height, t.t.internalFmt, buffer);
 				gl.compressedTexSubImage2D(face, mipLevel, 0, 0, pixels.width, pixels.height, t.t.internalFmt, buffer);
 		} else {
 		} else {
-			if( t.flags.has(IsArray) )
+			if( t.flags.has(IsArray) || t.flags.has(Is3D) )
 				gl.texSubImage3D(face, mipLevel, 0, 0, side, pixels.width, pixels.height, 1, getChannels(t.t), t.t.pixelFmt, buffer);
 				gl.texSubImage3D(face, mipLevel, 0, 0, side, pixels.width, pixels.height, 1, getChannels(t.t), t.t.pixelFmt, buffer);
 			else
 			else
 				gl.texSubImage2D(face, mipLevel, 0, 0, pixels.width, pixels.height, getChannels(t.t), t.t.pixelFmt, buffer);
 				gl.texSubImage2D(face, mipLevel, 0, 0, pixels.width, pixels.height, getChannels(t.t), t.t.pixelFmt, buffer);

+ 4 - 0
h3d/mat/Data.hx

@@ -134,6 +134,10 @@ enum TextureFlags {
 		Texture can be written in shaders using RWTexture
 		Texture can be written in shaders using RWTexture
 	**/
 	**/
 	Writable;
 	Writable;
+	/**
+		Tells if it's a 3D texture
+	**/
+	Is3D;
 }
 }
 
 
 typedef TextureFormat = hxd.PixelFormat;
 typedef TextureFormat = hxd.PixelFormat;

+ 5 - 1
h3d/mat/Texture.hx

@@ -190,7 +190,11 @@ class Texture {
 			str = "Texture_" + id;
 			str = "Texture_" + id;
 			if( allocPos != null ) str += "(" + allocPos.position + ")";
 			if( allocPos != null ) str += "(" + allocPos.position + ")";
 		}
 		}
-		return str+"("+width+"x"+height+")";
+		if ( flags.has(Is3D) )
+			str += "("+width+"x"+height+"x"+layerCount+")";
+		else
+			str += "("+width+"x"+height+")";
+		return str;
 	}
 	}
 
 
 	public function setName(n) {
 	public function setName(n) {

+ 32 - 0
h3d/mat/Texture3D.hx

@@ -0,0 +1,32 @@
+package h3d.mat;
+import h3d.mat.Data;
+
+class Texture3D extends Texture {
+
+	var depth : Int;
+
+	public function new(w, h, d, ?flags : Array<TextureFlags>, ?format : TextureFormat ) {
+		this.depth = d;
+		if( flags == null ) flags = [];
+		flags.push(Is3D);
+		super(w,h,flags,format);
+	}
+
+	override function get_layerCount() {
+		return depth;
+	}
+
+	override function clone() {
+		var old = lastFrame;
+		preventAutoDispose();
+		var t = new TextureArray(width, height, depth, null, format);
+		h3d.pass.Copy.run(this, t);
+		lastFrame = old;
+		return t;
+	}
+
+	override function toString() {
+		return super.toString()+"x("+depth+")";
+	}
+
+}

+ 1 - 1
hxsl/GlslOut.hx

@@ -177,7 +177,7 @@ class GlslOut {
 		case TSampler(dim,arr):
 		case TSampler(dim,arr):
 			var name = getSamplerType(dim,arr);
 			var name = getSamplerType(dim,arr);
 			add(name);
 			add(name);
-			if( isES && arr )
+			if( isES && (arr || dim == T3D) )
 				decl("precision lowp "+name+";");
 				decl("precision lowp "+name+";");
 		case TRWTexture(dim, arr, chans):
 		case TRWTexture(dim, arr, chans):
 			add("image"+dim.getName().substr(1)+(arr?"Array":""));
 			add("image"+dim.getName().substr(1)+(arr?"Array":""));