瀏覽代碼

Added support for compressed cube maps.

Fortunately here we don't need to flip the images.
alteredq 13 年之前
父節點
當前提交
fce601d5f0

文件差異過大導致無法顯示
+ 169 - 168
build/three.min.js


二進制
examples/textures/cube/escher/dds/nx.dds


二進制
examples/textures/cube/escher/dds/ny.dds


二進制
examples/textures/cube/escher/dds/nz.dds


二進制
examples/textures/cube/escher/dds/px.dds


二進制
examples/textures/cube/escher/dds/py.dds


二進制
examples/textures/cube/escher/dds/pz.dds


+ 10 - 0
examples/webgl_materials_cubemap_escher.html

@@ -70,6 +70,7 @@
 
 				scene = new THREE.Scene();
 
+				/*
 				var r = "textures/cube/Escher/";
 
 				var urls = [ r + "px.jpg", r + "nx.jpg",
@@ -77,6 +78,15 @@
 							 r + "pz.jpg", r + "nz.jpg" ];
 
 				var textureCube = THREE.ImageUtils.loadTextureCube( urls );
+				*/
+
+				var r = "textures/cube/Escher/dds/";
+
+				var urls = [ r + "px.dds", r + "nx.dds",
+							 r + "py.dds", r + "ny.dds",
+							 r + "pz.dds", r + "nz.dds" ];
+
+				var textureCube = THREE.ImageUtils.loadCompressedTextureCube( urls );
 				var material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube } )
 				var geometry = new THREE.SphereGeometry( 100, 96, 64 );
 

+ 105 - 29
src/extras/ImageUtils.js

@@ -36,19 +36,65 @@ THREE.ImageUtils = {
 
 	},
 
-	loadTextureCube: function ( array, mapping, onLoad ) {
+	loadCompressedTexture: function ( url, mapping, onLoad, onError ) {
 
-		var i, l, images = [];
-		var texture = new THREE.Texture( images, mapping );
+		var texture = new THREE.CompressedTexture();
+		texture.mapping = mapping;
 
-		texture.flipY = false;
+		var request = new XMLHttpRequest();
+
+		request.onload = function () {
+
+			var buffer = request.response;
+			var dds = THREE.ImageUtils.parseDDS( buffer, true );
+
+			texture.format = dds.format;
+
+			texture.mipmaps = dds.mipmaps;
+			texture.image.width = dds.width;
+			texture.image.height = dds.height;
+
+			// gl.generateMipmap fails for compressed textures
+			// mipmaps must be embedded in the DDS file
+			// or texture filters must not use mipmapping
+
+			texture.generateMipmaps = false;
+
+			texture.needsUpdate = true;
+
+			if ( onLoad ) onLoad( texture );
+
+		}
+
+		request.onerror = onError;
+
+		request.open( 'GET', url, true );
+		request.responseType = "arraybuffer";
+		request.send( null );
 
+		return texture;
+
+	},
+
+	loadTextureCube: function ( array, mapping, onLoad, onError ) {
+
+		var images = [];
 		images.loadCount = 0;
 
-		for ( i = 0, l = array.length; i < l; ++ i ) {
+		var texture = new THREE.Texture();
+		texture.image = images;
+		if ( mapping !== undefined ) texture.mapping = mapping;
+
+		// no flipping needed for cube textures
+
+		texture.flipY = false;
+
+		for ( var i = 0, il = array.length; i < il; ++ i ) {
 
-			images[ i ] = new Image();
-			images[ i ].onload = function () {
+			var cubeImage = new Image();
+			images[ i ] = cubeImage;
+
+			cubeImage.onload = function () {
 
 				images.loadCount += 1;
 
@@ -61,8 +107,10 @@ THREE.ImageUtils = {
 
 			};
 
-			images[ i ].crossOrigin = this.crossOrigin;
-			images[ i ].src = array[ i ];
+			cubeImage.onerror = onError;
+
+			cubeImage.crossOrigin = this.crossOrigin;
+			cubeImage.src = array[ i ];
 
 		}
 
@@ -70,41 +118,69 @@ THREE.ImageUtils = {
 
 	},
 
-	loadCompressedTexture: function ( url, mapping, onLoad, onError ) {
+	loadCompressedTextureCube: function ( array, mapping, onLoad, onError ) {
+
+		var images = [];
+		images.loadCount = 0;
 
 		var texture = new THREE.CompressedTexture();
-		texture.mapping = mapping;
+		texture.image = images;
+		if ( mapping !== undefined ) texture.mapping = mapping;
 
-		var xhr = new XMLHttpRequest();
+		// no flipping for cube textures
+		// (also flipping doesn't work for compressed textures )
 
-		xhr.onload = function () {
+		texture.flipY = false;
 
-			var buffer = xhr.response;
-			var dds = THREE.ImageUtils.parseDDS( buffer, true );
+		// can't generate mipmaps for compressed textures
+		// mips must be embedded in DDS files
 
-			texture.format = dds.format;
+		texture.generateMipmaps = false;
 
-			texture.mipmaps = dds.mipmaps;
-			texture.image.width = dds.width;
-			texture.image.height = dds.height;
+		var generateCubeFaceCallback = function ( rq, img ) {
 
-			// gl.generateMipmap fails for compressed textures
-			// mipmaps must be embedded in the DDS file
-			// or texture filters must not use mipmapping
+			return function () {
 
-			texture.generateMipmaps = false;
+				var buffer = rq.response;
+				var dds = THREE.ImageUtils.parseDDS( buffer, true );
 
-			texture.needsUpdate = true;
+				img.format = dds.format;
 
-			if ( onLoad ) onLoad( texture );
+				img.mipmaps = dds.mipmaps;
+				img.width = dds.width;
+				img.height = dds.height;
+
+				images.loadCount += 1;
+
+				if ( images.loadCount === 6 ) {
+
+					texture.format = dds.format;
+					texture.needsUpdate = true;
+					if ( onLoad ) onLoad();
+
+				}
+
+			}
 
 		}
 
-		xhr.onerror = onError;
+		for ( var i = 0, il = array.length; i < il; ++ i ) {
+
+			var cubeImage = {};
+			images[ i ] = cubeImage;
+
+			var request = new XMLHttpRequest();
 
-        xhr.open( 'GET', url, true );
-        xhr.responseType = "arraybuffer";
-		xhr.send( null );
+			request.onload = generateCubeFaceCallback( request, cubeImage );
+			request.onerror = onError;
+
+			var url = array[ i ];
+
+			request.open( 'GET', url, true );
+			request.responseType = "arraybuffer";
+			request.send( null );
+
+		}
 
 		return texture;
 

+ 19 - 2
src/renderers/WebGLRenderer.js

@@ -6340,11 +6340,13 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 				_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
 
+				var isCompressed = texture instanceof THREE.CompressedTexture;
+
 				var cubeImage = [];
 
 				for ( var i = 0; i < 6; i ++ ) {
 
-					if ( _this.autoScaleCubemaps ) {
+					if ( _this.autoScaleCubemaps && ! isCompressed ) {
 
 						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );
 
@@ -6365,7 +6367,22 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 				for ( var i = 0; i < 6; i ++ ) {
 
-					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
+					if ( isCompressed ) {
+
+						var mipmap, mipmaps = cubeImage[ i ].mipmaps;
+
+						for( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
+
+							mipmap = mipmaps[ j ];
+							_gl.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
+
+						}
+
+					} else {
+
+						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
+
+					}
 
 				}
 

+ 20 - 4
src/textures/CompressedTexture.js

@@ -15,11 +15,27 @@ THREE.CompressedTexture.prototype = Object.create( THREE.Texture.prototype );
 
 THREE.CompressedTexture.prototype.clone = function () {
 
-	var clonedTexture = new THREE.CompressedTexture( this.mipmaps, this.image.width, this.image.height, this.format, this.type, this.mapping, this.wrapS, this.wrapT, this.magFilter, this.minFilter );
+	var texture = new THREE.CompressedTexture();
 
-	clonedTexture.offset.copy( this.offset );
-	clonedTexture.repeat.copy( this.repeat );
+	texture.image = this.image;
+	texture.mipmaps = this.mipmaps;
 
-	return clonedTexture;
+	texture.format = this.format;
+	texture.type = this.type;
+
+	texture.mapping = this.mapping;
+
+	texture.wrapS = this.wrapS;
+	texture.wrapT = this.wrapT;
+
+	texture.magFilter = this.magFilter;
+	texture.minFilter = this.minFilter;
+
+	texture.anisotropy = this.anisotropy;
+
+	texture.offset.copy( this.offset );
+	texture.repeat.copy( this.repeat );
+
+	return texture;
 
 };

部分文件因文件數量過多而無法顯示