浏览代码

reduce gl texture state changes

Nicolas Cannasse 8 年之前
父节点
当前提交
7f8c3e270c
共有 2 个文件被更改,包括 29 次插入37 次删除
  1. 4 4
      h3d/impl/Driver.hx
  2. 25 33
      h3d/impl/GlDriver.hx

+ 4 - 4
h3d/impl/Driver.hx

@@ -9,25 +9,25 @@ 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 };
+typedef Texture = { t : js.html.webgl.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : 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 };
+typedef Texture = { t : nme.gl.GLTexture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : 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 };
+typedef Texture = { t : lime.graphics.opengl.GLTexture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int };
 typedef DepthBuffer = { r : lime.graphics.opengl.GLRenderbuffer };
 typedef Query = {};
 #elseif hxsdl
 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 };
+typedef Texture = { t : sdl.GL.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int };
 typedef DepthBuffer = { r : sdl.GL.Renderbuffer };
 typedef Query = { q : sdl.GL.Query, kind : QueryKind };
 #else

+ 25 - 33
h3d/impl/GlDriver.hx

@@ -103,6 +103,7 @@ class GlDriver extends Driver {
 	var numTargets : Int;
 
 	var debug : Bool;
+	var boundTextures : Array<h3d.mat.Texture> = [];
 
 	public function new() {
 		#if js
@@ -272,6 +273,7 @@ class GlDriver extends Driver {
 				#end
 			}
 		case Textures:
+			var tcount = s.textures.length;
 			for( i in 0...s.textures.length + s.cubeTextures.length ) {
 				var t = buf.tex[i];
 				if( t == null || t.isDisposed() ) {
@@ -283,42 +285,32 @@ class GlDriver extends Driver {
 					t.realloc();
 				}
 				t.lastFrame = frame;
-			}
-
-			for( i in 0...s.textures.length ) {
-				var t = buf.tex[i];
 
-				if( s.textures[i] == null ) continue;
+				var isCube = i >= tcount;
+				var pt = isCube ? s.cubeTextures[i - tcount] : s.textures[i];
+				if( pt == null ) continue;
+				if( boundTextures[i] == t ) continue;
+				boundTextures[i] = t;
 
+				var mode = isCube ? GL.TEXTURE_CUBE_MAP : GL.TEXTURE_2D;
 				gl.activeTexture(GL.TEXTURE0 + i);
-				gl.uniform1i(s.textures[i], i);
-
-				gl.bindTexture(GL.TEXTURE_2D, t.t.t);
-				var flags = TFILTERS[Type.enumIndex(t.mipMap)][Type.enumIndex(t.filter)];
-				gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, flags[0]);
-				gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, flags[1]);
-				var w = TWRAP[Type.enumIndex(t.wrap)];
-				gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, w);
-				gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, w);
-			}
-
-			for( i in 0...s.cubeTextures.length ) {
-				var t = buf.tex[i + s.textures.length];
-
-				if( s.cubeTextures[i] == null ) continue;
-
-				gl.activeTexture(GL.TEXTURE0 + i + s.textures.length);
-				gl.uniform1i(s.cubeTextures[i], i + s.textures.length);
-
-				gl.bindTexture(GL.TEXTURE_CUBE_MAP, t.t.t);
-				var flags = TFILTERS[Type.enumIndex(t.mipMap)][Type.enumIndex(t.filter)];
-				gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, flags[0]);
-				gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, flags[1]);
-				var w = TWRAP[Type.enumIndex(t.wrap)];
-				gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_S, w);
-				gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_T, w);
+				gl.uniform1i(pt, i);
+				gl.bindTexture(mode, t.t.t);
+
+				var mip = Type.enumIndex(t.mipMap);
+				var filter = Type.enumIndex(t.filter);
+				var wrap = Type.enumIndex(t.wrap);
+				var bits = mip | (filter << 3) | (wrap << 6);
+				if( bits != t.t.bits ) {
+					t.t.bits = bits;
+					var flags = TFILTERS[mip][filter];
+					gl.texParameteri(mode, GL.TEXTURE_MAG_FILTER, flags[0]);
+					gl.texParameteri(mode, GL.TEXTURE_MIN_FILTER, flags[1]);
+					var w = TWRAP[wrap];
+					gl.texParameteri(mode, GL.TEXTURE_WRAP_S, w);
+					gl.texParameteri(mode, GL.TEXTURE_WRAP_T, w);
+				}
 			}
-
 		}
 	}
 
@@ -527,7 +519,7 @@ 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 };
+		var tt : Texture = { t : tt, width : t.width, height : t.height, internalFmt : GL.RGBA, pixelFmt : GL.UNSIGNED_BYTE, bits : -1 };
 		switch( t.format ) {
 		case RGBA:
 			// default