Explorar o código

bugfix : uploading a texture might unbind another one

ncannasse %!s(int64=7) %!d(string=hai) anos
pai
achega
d1248d4989
Modificáronse 2 ficheiros con 25 adicións e 12 borrados
  1. 5 5
      h3d/impl/Driver.hx
  2. 20 7
      h3d/impl/GlDriver.hx

+ 5 - 5
h3d/impl/Driver.hx

@@ -9,31 +9,31 @@ typedef Query = {};
 #elseif js
 typedef IndexBuffer = js.html.webgl.Buffer;
 typedef VertexBuffer = { b : js.html.webgl.Buffer, stride : Int };
-typedef Texture = { t : js.html.webgl.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int };
+typedef Texture = { t : js.html.webgl.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int };
 typedef DepthBuffer = { r : js.html.webgl.Renderbuffer };
 typedef Query = {};
 #elseif nme
 typedef IndexBuffer = nme.gl.GLBuffer;
 typedef VertexBuffer = { b : nme.gl.GLBuffer, stride : Int };
-typedef Texture = { t : nme.gl.GLTexture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int };
+typedef Texture = { t : nme.gl.GLTexture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int };
 typedef DepthBuffer = { r : nme.gl.Renderbuffer };
 typedef Query = {};
 #elseif lime
 typedef IndexBuffer = lime.graphics.opengl.GLBuffer;
 typedef VertexBuffer = { b : lime.graphics.opengl.GLBuffer, stride : Int };
-typedef Texture = { t : lime.graphics.opengl.GLTexture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int };
+typedef Texture = { t : lime.graphics.opengl.GLTexture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int };
 typedef DepthBuffer = { r : lime.graphics.opengl.GLRenderbuffer };
 typedef Query = {};
 #elseif hlsdl
 typedef IndexBuffer = sdl.GL.Buffer;
 typedef VertexBuffer = { b : sdl.GL.Buffer, stride : Int };
-typedef Texture = { t : sdl.GL.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int };
+typedef Texture = { t : sdl.GL.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int };
 typedef DepthBuffer = { r : sdl.GL.Renderbuffer };
 typedef Query = { q : sdl.GL.Query, kind : QueryKind };
 #elseif usegl
 typedef IndexBuffer = haxe.GLTypes.Buffer;
 typedef VertexBuffer = { b : haxe.GLTypes.Buffer, stride : Int };
-typedef Texture = { t : haxe.GLTypes.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int };
+typedef Texture = { t : haxe.GLTypes.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int };
 typedef DepthBuffer = { r : haxe.GLTypes.Renderbuffer };
 typedef Query = { q : haxe.GLTypes.Query, kind : QueryKind };
 #elseif hldx

+ 20 - 7
h3d/impl/GlDriver.hx

@@ -126,6 +126,7 @@ class GlDriver extends Driver {
 	var defStencil : Stencil;
 	var programs : Map<Int, CompiledProgram>;
 	var frame : Int;
+	var lastActiveIndex : Int = 0;
 
 	var bufferWidth : Int;
 	var bufferHeight : Int;
@@ -390,6 +391,7 @@ class GlDriver extends Driver {
 				gl.activeTexture(GL.TEXTURE0 + i);
 				gl.uniform1i(pt, i);
 				gl.bindTexture(mode, t.t.t);
+				lastActiveIndex = i;
 
 				var mip = Type.enumIndex(t.mipMap);
 				var filter = Type.enumIndex(t.filter);
@@ -615,7 +617,8 @@ class GlDriver extends Driver {
 
 	override function allocTexture( t : h3d.mat.Texture ) : Texture {
 		var tt = gl.createTexture();
-		var tt : Texture = { t : tt, width : t.width, height : t.height, internalFmt : GL.RGBA, pixelFmt : GL.UNSIGNED_BYTE, bits : -1 };
+		var bind = t.flags.has(Cube) ? GL.TEXTURE_CUBE_MAP : GL.TEXTURE_2D;
+		var tt : Texture = { t : tt, width : t.width, height : t.height, internalFmt : GL.RGBA, pixelFmt : GL.UNSIGNED_BYTE, bits : -1, bind : bind };
 		switch( t.format ) {
 		case RGBA:
 			// default
@@ -646,7 +649,6 @@ class GlDriver extends Driver {
 		}
 		t.lastFrame = frame;
 		t.flags.unset(WasCleared);
-		var bind = t.flags.has(Cube) ? GL.TEXTURE_CUBE_MAP : GL.TEXTURE_2D;
 		gl.bindTexture(bind, tt.t);
 		var outOfMem = false;
 		if( t.flags.has(Cube) ) {
@@ -662,7 +664,7 @@ class GlDriver extends Driver {
 			if( gl.getError() == GL.OUT_OF_MEMORY )
 				outOfMem = true;
 		}
-		gl.bindTexture(bind, null);
+		restoreBind();
 
 		if( outOfMem ) {
 			gl.deleteTexture(tt.t);
@@ -672,6 +674,14 @@ class GlDriver extends Driver {
 		return tt;
 	}
 
+	function restoreBind() {
+		var t = boundTextures[lastActiveIndex];
+		if( t == null )
+			gl.bindTexture(GL.TEXTURE_2D, null);
+		else
+			gl.bindTexture(t.bind, t.t);
+	}
+
 	override function allocDepthBuffer( b : h3d.mat.DepthBuffer ) : DepthBuffer {
 		var r = gl.createRenderbuffer();
 		gl.bindRenderbuffer(GL.RENDERBUFFER, r);
@@ -742,6 +752,9 @@ class GlDriver extends Driver {
 		var tt = t.t;
 		if( tt == null ) return;
 		t.t = null;
+		for( i in 0...boundTextures.length )
+			if( boundTextures[i] == tt )
+				boundTextures[i] = null;
 		gl.deleteTexture(tt.t);
 	}
 
@@ -757,7 +770,7 @@ class GlDriver extends Driver {
 		var bind = t.flags.has(Cube) ? GL.TEXTURE_CUBE_MAP : GL.TEXTURE_2D;
 		gl.bindTexture(bind, t.t.t);
 		gl.generateMipmap(bind);
-		gl.bindTexture(bind, null);
+		restoreBind();
 	}
 
 	override function uploadTextureBitmap( t : h3d.mat.Texture, bmp : hxd.BitmapData, mipLevel : Int, side : Int ) {
@@ -777,7 +790,7 @@ class GlDriver extends Driver {
 			gl.pixelStorei(GL.UNPACK_FLIP_Y_WEBGL, 1);
 			#end
 			gl.texImage2D(GL.TEXTURE_2D, mipLevel, t.t.internalFmt, getChannels(t.t), t.t.pixelFmt, img.getImageData(0, 0, bmp.width, bmp.height));
-			gl.bindTexture(GL.TEXTURE_2D, null);
+			restoreBind();
 		}
 	#end
 	}
@@ -864,7 +877,7 @@ class GlDriver extends Driver {
 		gl.pixelStorei(GL.UNPACK_FLIP_Y_WEBGL, cubic ? 0 : 1);
 		gl.texImage2D(face, mipLevel, t.t.internalFmt, pixels.width, pixels.height, 0, getChannels(t.t), t.t.pixelFmt, bytesToUint8Array(pixels.bytes));
 		#end
-		gl.bindTexture(bind, null);
+		restoreBind();
 	}
 
 	override function uploadVertexBuffer( v : VertexBuffer, startVertex : Int, vertexCount : Int, buf : hxd.FloatBuffer, bufPos : Int ) {
@@ -1039,7 +1052,7 @@ class GlDriver extends Driver {
 			var bind = tex.flags.has(Cube) ? GL.TEXTURE_CUBE_MAP : GL.TEXTURE_2D;
 			gl.bindTexture(bind, tex.t.t);
 			gl.generateMipmap(bind);
-			gl.bindTexture(bind, null);
+			restoreBind();
 		}
 
 		tex.flags.set(WasCleared); // once we draw to, do not clear again