瀏覽代碼

one more (last?) gl textures coordinates fix: flip whole output by -1 if render target

ncannasse 7 年之前
父節點
當前提交
8cbdf93f08
共有 10 個文件被更改,包括 31 次插入35 次删除
  1. 7 3
      h2d/RenderContext.hx
  2. 0 4
      h3d/Camera.hx
  3. 6 1
      h3d/impl/GlDriver.hx
  4. 2 15
      h3d/pass/Border.hx
  5. 1 0
      h3d/pass/Default.hx
  6. 4 3
      h3d/pass/ScreenFx.hx
  7. 4 5
      h3d/prim/Plane2D.hx
  8. 2 1
      h3d/shader/BaseMesh.hx
  9. 3 1
      h3d/shader/ScreenShader.hx
  10. 2 2
      hxsl/GlslOut.hx

+ 7 - 3
h2d/RenderContext.hx

@@ -45,6 +45,8 @@ class RenderContext extends h3d.impl.RenderContext {
 	var renderW : Float;
 	var renderW : Float;
 	var renderH : Float;
 	var renderH : Float;
 	var currentBlend : BlendMode;
 	var currentBlend : BlendMode;
+	var baseFlipY : Float;
+	var targetFlipY : Float;
 
 
 	public function new(scene) {
 	public function new(scene) {
 		super();
 		super();
@@ -83,6 +85,8 @@ class RenderContext extends h3d.impl.RenderContext {
 		stride = 0;
 		stride = 0;
 		curX = 0;
 		curX = 0;
 		curY = 0;
 		curY = 0;
+		targetFlipY = engine.driver.hasFeature(BottomLeftCoords) ? -1 : 1;
+		baseFlipY = engine.getCurrentTarget() != null ? targetFlipY : 1;
 		inFilter = null;
 		inFilter = null;
 		curWidth = scene.width;
 		curWidth = scene.width;
 		curHeight = scene.height;
 		curHeight = scene.height;
@@ -90,7 +94,7 @@ class RenderContext extends h3d.impl.RenderContext {
 		// todo : we might prefer to auto-detect this by running a test and capturing its output
 		// todo : we might prefer to auto-detect this by running a test and capturing its output
 		baseShader.pixelAlign = #if flash true #else false #end;
 		baseShader.pixelAlign = #if flash true #else false #end;
 		baseShader.halfPixelInverse.set(0.5 / engine.width, 0.5 / engine.height);
 		baseShader.halfPixelInverse.set(0.5 / engine.width, 0.5 / engine.height);
-		baseShader.viewport.set( -scene.width * 0.5, -scene.height * 0.5, 2 / scene.width, -2 / scene.height);
+		baseShader.viewport.set( -scene.width * 0.5, -scene.height * 0.5, 2 / scene.width, -2 * baseFlipY / scene.height);
 		baseShader.filterMatrixA.set(1, 0, 0);
 		baseShader.filterMatrixA.set(1, 0, 0);
 		baseShader.filterMatrixB.set(0, 1, 0);
 		baseShader.filterMatrixB.set(0, 1, 0);
 		baseShaderList.next = null;
 		baseShaderList.next = null;
@@ -154,7 +158,7 @@ class RenderContext extends h3d.impl.RenderContext {
 		if( width < 0 ) width = t == null ? scene.width : t.width;
 		if( width < 0 ) width = t == null ? scene.width : t.width;
 		if( height < 0 ) height = t == null ? scene.height : t.height;
 		if( height < 0 ) height = t == null ? scene.height : t.height;
 		baseShader.halfPixelInverse.set(0.5 / (t == null ? engine.width : t.width), 0.5 / (t == null ? engine.height : t.height));
 		baseShader.halfPixelInverse.set(0.5 / (t == null ? engine.width : t.width), 0.5 / (t == null ? engine.height : t.height));
-		baseShader.viewport.set( -width * 0.5 - startX, -height * 0.5 - startY, 2 / width, -2 / height);
+		baseShader.viewport.set( -width * 0.5 - startX, -height * 0.5 - startY, 2 / width, -2 * targetFlipY / height);
 		targetsStackIndex++;
 		targetsStackIndex++;
 		if( targetsStackIndex > targetsStack.length ){
 		if( targetsStackIndex > targetsStack.length ){
 			targetsStack.push( { t : t, x : startX, y : startY, w : width, h : height, hasRZ: hasRenderZone, rzX: renderX, rzY:renderY, rzW:renderW, rzH:renderH } );
 			targetsStack.push( { t : t, x : startX, y : startY, w : width, h : height, hasRZ: hasRenderZone, rzX: renderX, rzY:renderY, rzW:renderW, rzH:renderH } );
@@ -193,7 +197,7 @@ class RenderContext extends h3d.impl.RenderContext {
 			var height = tinf == null ? scene.height : tinf.h;
 			var height = tinf == null ? scene.height : tinf.h;
 			initShaders(baseShaderList);
 			initShaders(baseShaderList);
 			baseShader.halfPixelInverse.set(0.5 / (t == null ? engine.width : t.width), 0.5 / (t == null ? engine.height : t.height));
 			baseShader.halfPixelInverse.set(0.5 / (t == null ? engine.width : t.width), 0.5 / (t == null ? engine.height : t.height));
-			baseShader.viewport.set( -width * 0.5 - startX, -height * 0.5 - startY, 2 / width, -2 / height);
+			baseShader.viewport.set( -width * 0.5 - startX, -height * 0.5 - startY, 2 / width, -2 * (t == null ? baseFlipY : targetFlipY) / height);
 			curX = startX;
 			curX = startX;
 			curY = startY;
 			curY = startY;
 			curWidth = width;
 			curWidth = width;

+ 0 - 4
h3d/Camera.hx

@@ -126,10 +126,6 @@ class Camera {
 		case 4: dz = 1; up.set(0,1,0);
 		case 4: dz = 1; up.set(0,1,0);
 		case 5: dz = -1; up.set(0,1,0);
 		case 5: dz = -1; up.set(0,1,0);
 		}
 		}
-		#if !hldx
-		rightHanded = true;
-		up.scale3(-1);
-		#end
 		pos.set(0,0,0);
 		pos.set(0,0,0);
 		target.set(dx,dy,dz);
 		target.set(dx,dy,dz);
 		setFovX(90,1);
 		setFovX(90,1);

+ 6 - 1
h3d/impl/GlDriver.hx

@@ -518,7 +518,12 @@ class GlDriver extends Driver {
 
 
 	override function selectMaterial( pass : Pass ) {
 	override function selectMaterial( pass : Pass ) {
 		var bits = @:privateAccess pass.bits;
 		var bits = @:privateAccess pass.bits;
-		if( rightHanded ) {
+		/*
+			When rendering to a render target, our output will be flipped in Y to match
+			output texture coordinates. We also need to flip our culling.
+			The result is inverted if we are using a right handed camera.
+		*/
+		if( (curTarget == null) == rightHanded ) {
 			switch( pass.culling ) {
 			switch( pass.culling ) {
 			case Back: bits = (bits & ~Pass.culling_mask) | (2 << Pass.culling_offset);
 			case Back: bits = (bits & ~Pass.culling_mask) | (2 << Pass.culling_offset);
 			case Front: bits = (bits & ~Pass.culling_mask) | (1 << Pass.culling_offset);
 			case Front: bits = (bits & ~Pass.culling_mask) | (1 << Pass.culling_offset);

+ 2 - 15
h3d/pass/Border.hx

@@ -1,25 +1,12 @@
 package h3d.pass;
 package h3d.pass;
 
 
-private class BorderShader extends hxsl.Shader {
+private class BorderShader extends h3d.shader.ScreenShader {
 	static var SRC = {
 	static var SRC = {
 
 
 		@param var color : Vec4;
 		@param var color : Vec4;
 
 
-		@input var input : {
-			var position : Vec2;
-		};
-
-		var output : {
-			var position : Vec4;
-			var color : Vec4;
-		};
-
-		function vertex() {
-			output.position = vec4(input.position, 0, 1);
-		}
-
 		function fragment() {
 		function fragment() {
-			output.color = color;
+			pixelColor = color;
 		}
 		}
 
 
 	}
 	}

+ 1 - 0
h3d/pass/Default.hx

@@ -22,6 +22,7 @@ class Default extends Base {
 	@global("camera.proj") var cameraProj : h3d.Matrix = ctx.camera.mproj;
 	@global("camera.proj") var cameraProj : h3d.Matrix = ctx.camera.mproj;
 	@global("camera.position") var cameraPos : h3d.Vector = ctx.camera.pos;
 	@global("camera.position") var cameraPos : h3d.Vector = ctx.camera.pos;
 	@global("camera.projDiag") var cameraProjDiag : h3d.Vector = new h3d.Vector(ctx.camera.mproj._11,ctx.camera.mproj._22,ctx.camera.mproj._33,ctx.camera.mproj._44);
 	@global("camera.projDiag") var cameraProjDiag : h3d.Vector = new h3d.Vector(ctx.camera.mproj._11,ctx.camera.mproj._22,ctx.camera.mproj._33,ctx.camera.mproj._44);
+	@global("camera.projFlip") var cameraProjFlip : Float = ctx.engine.driver.hasFeature(BottomLeftCoords) && ctx.engine.getCurrentTarget() != null ? -1 : 1;
 	@global("camera.viewProj") var cameraViewProj : h3d.Matrix = ctx.camera.m;
 	@global("camera.viewProj") var cameraViewProj : h3d.Matrix = ctx.camera.m;
 	@global("camera.inverseViewProj") var cameraInverseViewProj : h3d.Matrix = ctx.camera.getInverseViewProj();
 	@global("camera.inverseViewProj") var cameraInverseViewProj : h3d.Matrix = ctx.camera.getInverseViewProj();
 	@global("global.time") var globalTime : Float = ctx.time;
 	@global("global.time") var globalTime : Float = ctx.time;

+ 4 - 3
h3d/pass/ScreenFx.hx

@@ -1,6 +1,6 @@
 package h3d.pass;
 package h3d.pass;
 
 
-class ScreenFx<T:hxsl.Shader> {
+class ScreenFx<T:h3d.shader.ScreenShader> {
 
 
 	public var shader : T;
 	public var shader : T;
 	public var pass : h3d.mat.Pass;
 	public var pass : h3d.mat.Pass;
@@ -10,10 +10,10 @@ class ScreenFx<T:hxsl.Shader> {
 	var shaders : hxsl.ShaderList;
 	var shaders : hxsl.ShaderList;
 	var buffers : h3d.shader.Buffers;
 	var buffers : h3d.shader.Buffers;
 
 
-	public function new(shader) {
+	public function new(shader, ?output) {
 		this.shader = shader;
 		this.shader = shader;
 		shaders = new hxsl.ShaderList(shader);
 		shaders = new hxsl.ShaderList(shader);
-		manager = new ShaderManager();
+		manager = new ShaderManager(output);
 		pass = new h3d.mat.Pass(Std.string(this), new hxsl.ShaderList(shader));
 		pass = new h3d.mat.Pass(Std.string(this), new hxsl.ShaderList(shader));
 		pass.culling = None;
 		pass.culling = None;
 		pass.depth(false, Always);
 		pass.depth(false, Always);
@@ -55,6 +55,7 @@ class ScreenFx<T:hxsl.Shader> {
 
 
 	public function render() {
 	public function render() {
 		var rts = manager.compileShaders(shaders);
 		var rts = manager.compileShaders(shaders);
+		shader.flipY = engine.driver.hasFeature(BottomLeftCoords) && engine.getCurrentTarget() != null ? -1 : 1;
 		engine.selectMaterial(pass);
 		engine.selectMaterial(pass);
 		engine.selectShader(rts);
 		engine.selectShader(rts);
 		if( buffers == null )
 		if( buffers == null )

+ 4 - 5
h3d/prim/Plane2D.hx

@@ -15,26 +15,25 @@ class Plane2D extends Primitive {
 
 
 	override function alloc( engine : h3d.Engine ) {
 	override function alloc( engine : h3d.Engine ) {
 		var v = new hxd.FloatBuffer();
 		var v = new hxd.FloatBuffer();
-		var y = engine.driver.hasFeature(BottomLeftCoords) ? 1. : 0.;
 		v.push( -1);
 		v.push( -1);
 		v.push( -1);
 		v.push( -1);
 		v.push( 0);
 		v.push( 0);
-		v.push( 1 - y);
+		v.push( 1 );
 
 
 		v.push( -1);
 		v.push( -1);
 		v.push( 1);
 		v.push( 1);
 		v.push( 0);
 		v.push( 0);
-		v.push( y);
+		v.push( 0);
 
 
 		v.push( 1);
 		v.push( 1);
 		v.push( -1);
 		v.push( -1);
 		v.push( 1);
 		v.push( 1);
-		v.push( 1 - y);
+		v.push( 1);
 
 
 		v.push( 1);
 		v.push( 1);
 		v.push( 1);
 		v.push( 1);
 		v.push( 1);
 		v.push( 1);
-		v.push( y);
+		v.push( 0);
 
 
 		buffer = h3d.Buffer.ofFloats(v, 4, [Quads, RawFormat]);
 		buffer = h3d.Buffer.ofFloats(v, 4, [Quads, RawFormat]);
 	}
 	}

+ 2 - 1
h3d/shader/BaseMesh.hx

@@ -8,6 +8,7 @@ class BaseMesh extends hxsl.Shader {
 			var view : Mat4;
 			var view : Mat4;
 			var proj : Mat4;
 			var proj : Mat4;
 			var position : Vec3;
 			var position : Vec3;
+			var projFlip : Float;
 			var projDiag : Vec3;
 			var projDiag : Vec3;
 			var viewProj : Mat4;
 			var viewProj : Mat4;
 			var inverseViewProj : Mat4;
 			var inverseViewProj : Mat4;
@@ -75,7 +76,7 @@ class BaseMesh extends hxsl.Shader {
 		}
 		}
 
 
 		function vertex() {
 		function vertex() {
-			output.position = projectedPosition;
+			output.position = projectedPosition * vec4(1, camera.projFlip, 1, 1);
 			pixelTransformedPosition = transformedPosition;
 			pixelTransformedPosition = transformedPosition;
 		}
 		}
 
 

+ 3 - 1
h3d/shader/ScreenShader.hx

@@ -8,6 +8,8 @@ class ScreenShader extends hxsl.Shader {
 			uv : Vec2,
 			uv : Vec2,
 		};
 		};
 
 
+		@param var flipY : Float;
+
 		var output : {
 		var output : {
 			position : Vec4,
 			position : Vec4,
 			color : Vec4,
 			color : Vec4,
@@ -22,7 +24,7 @@ class ScreenShader extends hxsl.Shader {
 
 
 		function vertex() {
 		function vertex() {
 			calculatedUV = input.uv;
 			calculatedUV = input.uv;
-			output.position = vec4(input.position, 0, 1);
+			output.position = vec4(input.position.x, input.position.y * flipY, 0, 1);
 		}
 		}
 	};
 	};
 
 

+ 2 - 2
hxsl/GlslOut.hx

@@ -247,9 +247,9 @@ class GlslOut {
 			decl("mat3 _mat3( _mat3x4 v ) { return mat3(v.a.xyz,v.b.xyz,v.c.xyz); }");
 			decl("mat3 _mat3( _mat3x4 v ) { return mat3(v.a.xyz,v.b.xyz,v.c.xyz); }");
 			return "_mat3";
 			return "_mat3";
 		case ScreenToUv:
 		case ScreenToUv:
-			decl("vec2 screenToUv( vec2 v ) { return v * vec2(0.5,0.5) + vec2(0.5,0.5); }");
+			decl("vec2 screenToUv( vec2 v ) { return v * vec2(0.5,-0.5) + vec2(0.5,0.5); }");
 		case UvToScreen:
 		case UvToScreen:
-			decl("vec2 uvToScreen( vec2 v ) { return v * vec2(2.,2.) + vec2(-1., -1.); }");
+			decl("vec2 uvToScreen( vec2 v ) { return v * vec2(2.,-2.) + vec2(-1., 1.); }");
 		default:
 		default:
 		}
 		}
 		return GLOBALS.get(g);
 		return GLOBALS.get(g);