Browse Source

Added support for compressed cube maps.

Fortunately here we don't need to flip the images.
alteredq 13 years ago
parent
commit
fce601d5f0

File diff suppressed because it is too large
+ 169 - 168
build/three.min.js


BIN
examples/textures/cube/escher/dds/nx.dds


BIN
examples/textures/cube/escher/dds/ny.dds


BIN
examples/textures/cube/escher/dds/nz.dds


BIN
examples/textures/cube/escher/dds/px.dds


BIN
examples/textures/cube/escher/dds/py.dds


BIN
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;
 
 };

Some files were not shown because too many files changed in this diff