소스 검색

more texture formats : R,RG,RGB with various bit size

ncannasse 7 년 전
부모
커밋
4213a23778
4개의 변경된 파일99개의 추가작업 그리고 33개의 파일을 삭제
  1. 16 3
      h3d/impl/DirectXDriver.hx
  2. 51 22
      h3d/impl/GlDriver.hx
  3. 11 3
      hxd/PixelFormat.hx
  4. 21 5
      hxd/Pixels.hx

+ 16 - 3
h3d/impl/DirectXDriver.hx

@@ -340,14 +340,27 @@ class DirectXDriver extends h3d.impl.Driver {
 		captureTexPixels(pixels, rt, 0, 0);
 	}
 
+	override function isSupportedFormat( fmt : hxd.PixelFormat ) {
+		return switch( fmt ) {
+		case RGB8, RGB16F: false;
+		default: true;
+		}
+	}
+
 	function getTextureFormat( t : h3d.mat.Texture ) : dx.Format {
 		return switch( t.format ) {
 		case RGBA: R8G8B8A8_UNORM;
 		case RGBA16F: R16G16B16A16_FLOAT;
 		case RGBA32F: R32G32B32A32_FLOAT;
-		case ALPHA32F: R32_FLOAT;
-		case ALPHA16F: R16_FLOAT;
-		case ALPHA8: R8_UNORM;
+		case R32F: R32_FLOAT;
+		case R16F: R16_FLOAT;
+		case R8: R8_UNORM;
+		case RG8: R8G8_UNORM;
+		case RG16F: R16G16_FLOAT;
+		case RG32F: R32G32_FLOAT;
+		case RGB32F: R32G32B32_FLOAT;
+		case RGB10A2: R10G10B10A2_UNORM;
+		case RG11B10UF: R11G11B10_FLOAT;
 		default: throw "Unsupported texture format " + t.format;
 		}
 	}

+ 51 - 22
h3d/impl/GlDriver.hx

@@ -21,8 +21,8 @@ private extern class GL2 extends js.html.webgl.GL {
 	function texImage3D(target : Int, level : Int, internalformat : Int, width : Int, height : Int, depth : Int, border : Int, format : Int, type : Int, source : Dynamic) : Void;
 	static inline var RGBA16F = 0x881A;
 	static inline var RGBA32F = 0x8814;
-	static inline var ALPHA16F = 0x881C;
-	static inline var ALPHA32F = 0x8816;
+	static inline var RED      = 0x1903;
+	static inline var RG       = 0x8227;
 	static inline var RGBA8	   = 0x8058;
 	static inline var BGRA 		 = 0x80E1;
 	static inline var HALF_FLOAT = 0x140B;
@@ -30,6 +30,8 @@ private extern class GL2 extends js.html.webgl.GL {
 	static inline var SRGB8      = 0x8C41;
 	static inline var SRGB_ALPHA = 0x8C42;
 	static inline var SRGB8_ALPHA = 0x8C43;
+	static inline var R11F_G11F_B10F = 0x8C3A;
+	static inline var RGB10_A2     = 0x8059;
 	static inline var DEPTH_COMPONENT24 = 0x81A6;
 	static inline var UNIFORM_BUFFER = 0x8A11;
 	static inline var TEXTURE_2D_ARRAY = 0x8C1A;
@@ -711,20 +713,26 @@ class GlDriver extends Driver {
 	function getChannels( t : Texture ) {
 		return switch( t.internalFmt ) {
 		case GL2.RGBA32F, GL2.RGBA16F, GL2.SRGB_ALPHA, GL2.SRGB8_ALPHA: GL.RGBA;
-		case GL2.ALPHA16F, GL2.ALPHA32F: GL.ALPHA;
 		case GL2.RGBA8: GL2.BGRA;
 		case GL2.SRGB, GL2.SRGB8: GL.RGB;
 		case GL.RGBA: GL.RGBA;
-		case GL.ALPHA: GL.ALPHA;
+		case GL.RGB: GL.RGB;
+		case GL2.R11F_G11F_B10F: GL.RGB;
+		case GL2.RGB10_A2: GL.RGBA;
+		#if (!hlsdl || (hlsdl >= "1.7"))
+		case GL2.RED: GL2.RED;
+		case GL2.RG: GL2.RG;
+		#end
 		default: throw "Invalid format " + t.internalFmt;
 		}
 	}
 
 	override function isSupportedFormat( fmt : h3d.mat.Data.TextureFormat ) {
 		return switch( fmt ) {
-		case RGBA, ALPHA8: true;
-		case RGBA16F, RGBA32F, ALPHA16F, ALPHA32F: hasFeature(FloatTextures);
+		case RGBA: true;
+		case RGBA16F, RGBA32F: hasFeature(FloatTextures);
 		case SRGB, SRGB_ALPHA: hasFeature(SRGBTextures);
+		case R16F, RG16F, RGB16F, R32F, RG32F, RGB32F, RG11B10UF, RGB10A2: #if js glES >= 3 #else true #end;
 		default: false;
 		}
 	}
@@ -742,26 +750,39 @@ class GlDriver extends Driver {
 		switch( t.format ) {
 		case RGBA:
 			// default
-		case ALPHA8:
-			tt.internalFmt = GL.ALPHA;
 		case RGBA32F if( hasFeature(FloatTextures) ):
 			tt.internalFmt = GL2.RGBA32F;
 			tt.pixelFmt = GL.FLOAT;
 		case RGBA16F if( hasFeature(FloatTextures) ):
 			tt.pixelFmt = GL2.HALF_FLOAT;
 			tt.internalFmt = GL2.RGBA16F;
-		case ALPHA16F if( hasFeature(FloatTextures) ):
-			tt.pixelFmt = GL2.HALF_FLOAT;
-			tt.internalFmt = GL2.ALPHA16F;
-		case ALPHA32F if( hasFeature(FloatTextures) ):
-			tt.pixelFmt = GL.FLOAT;
-			tt.internalFmt = GL2.ALPHA32F;
 		case BGRA:
 			tt.internalFmt = GL2.RGBA8;
 		case SRGB:
 			tt.internalFmt = GL2.SRGB8;
 		case SRGB_ALPHA:
 			tt.internalFmt = GL2.SRGB8_ALPHA;
+		case RGB8:
+			tt.internalFmt = GL.RGB;
+		#if (!hlsdl || (hlsdl >= "1.7"))
+		case R8:
+			tt.internalFmt = GL2.RED;
+		case RG8:
+			tt.internalFmt = GL2.RG;
+		case R16F:
+			tt.internalFmt = GL2.RED;
+			tt.pixelFmt = GL2.HALF_FLOAT;
+		case RG16F:
+			tt.internalFmt = GL2.RG;
+			tt.pixelFmt = GL2.HALF_FLOAT;
+		#end
+		case RGB16F:
+			tt.internalFmt = GL.RGB;
+			tt.pixelFmt = GL2.HALF_FLOAT;
+		case RG11B10UF:
+			tt.internalFmt = GL.R11F_G11F_B10F;
+		case RGB10A2:
+			tt.internalFmt = GL2.RGB10_A2;
 		default:
 			throw "Unsupported texture format "+t.format;
 		}
@@ -769,24 +790,30 @@ class GlDriver extends Driver {
 		t.flags.unset(WasCleared);
 		gl.bindTexture(bind, tt.t);
 		var outOfMem = false;
+
+		inline function checkError() {
+			var err = gl.getError();
+			if( err == GL.OUT_OF_MEMORY ) {
+				outOfMem = true;
+				return true;
+			}
+			if( err != 0 ) throw "Failed to alloc texture "+t.format+"(error "+err+")";
+			return false;
+		}
+
 		if( t.flags.has(Cube) ) {
 			for( i in 0...6 ) {
 				gl.texImage2D(CUBE_FACES[i], 0, tt.internalFmt, tt.width, tt.height, 0, getChannels(tt), tt.pixelFmt, null);
-				if( gl.getError() == GL.OUT_OF_MEMORY ) {
-					outOfMem = true;
-					break;
-				}
+				if( checkError() ) break;
 			}
 		#if (!hlsdl || (hlsdl >= "1.7"))
 		} else if( t.flags.has(IsArray) ) {
 			gl.texImage3D(GL2.TEXTURE_2D_ARRAY, 0, tt.internalFmt, tt.width, tt.height, t.layerCount, 0, getChannels(tt), tt.pixelFmt, null);
-			if( gl.getError() == GL.OUT_OF_MEMORY )
-				outOfMem = true;
+			checkError();
 		#end
 		} else {
 			gl.texImage2D(bind, 0, tt.internalFmt, tt.width, tt.height, 0, getChannels(tt), tt.pixelFmt, null);
-			if( gl.getError() == GL.OUT_OF_MEMORY )
-				outOfMem = true;
+			checkError();
 		}
 		restoreBind();
 
@@ -1381,6 +1408,8 @@ class GlDriver extends Driver {
 		#end
 		#if (js || hl)
 		gl.readPixels(0, 0, pixels.width, pixels.height, getChannels(curTarget.t), curTarget.t.pixelFmt, buffer);
+		var error = gl.getError();
+		if( error != 0 ) throw "Failed to capture pixels (error "+error+")";
 		@:privateAccess pixels.innerFormat = curTarget.format;
 		#end
 	}

+ 11 - 3
hxd/PixelFormat.hx

@@ -6,9 +6,17 @@ enum PixelFormat {
 	RGBA;
 	RGBA16F;
 	RGBA32F;
-	ALPHA8;
-	ALPHA16F;
-	ALPHA32F;
+	R8;
+	R16F;
+	R32F;
+	RG8;
+	RG16F;
+	RG32F;
+	RGB8;
+	RGB16F;
+	RGB32F;
 	SRGB;
 	SRGB_ALPHA;
+	RGB10A2;
+	RG11B10UF; // unsigned float
 }

+ 21 - 5
hxd/Pixels.hx

@@ -387,12 +387,20 @@ class Pixels {
 
 	public static function getBytesPerPixel( format : PixelFormat ) {
 		return switch( format ) {
-		case ALPHA8: 1;
 		case ARGB, BGRA, RGBA, SRGB, SRGB_ALPHA: 4;
 		case RGBA16F: 8;
 		case RGBA32F: 16;
-		case ALPHA16F: 2;
-		case ALPHA32F: 4;
+		case R8: 1;
+		case R16F: 2;
+		case R32F: 4;
+		case RG8: 2;
+		case RG16F: 4;
+		case RG32F: 8;
+		case RGB8: 3;
+		case RGB16F: 6;
+		case RGB32F: 12;
+		case RGB10A2: 4;
+		case RG11B10UF: 4;
 		}
 	}
 
@@ -402,8 +410,14 @@ class Pixels {
 	**/
 	public static function getChannelOffset( format : PixelFormat, channel : Channel ) {
 		return switch( format ) {
-		case ALPHA8, ALPHA16F, ALPHA32F:
-			if( channel == A ) 0 else -1;
+		case R8, R16F, R32F:
+			if( channel == R ) 0 else -1;
+		case RG8, RG16F, RG32F:
+			var p = getBytesPerPixel(format);
+			[0, p, -1, -1][channel.toInt()];
+		case RGB8, RGB16F, RGB32F:
+			var p = getBytesPerPixel(format);
+			[0, p, p<<1, -1][channel.toInt()];
 		case ARGB:
 			[1, 2, 3, 0][channel.toInt()];
 		case BGRA:
@@ -414,6 +428,8 @@ class Pixels {
 			channel.toInt() * 2;
 		case RGBA32F:
 			channel.toInt() * 4;
+		case RGB10A2, RG11B10UF:
+			throw "Bit packed format";
 		}
 	}