Browse Source

GLTFExporter: Add forcePowerOfTwoTexture option.

Takahiro 7 years ago
parent
commit
af03a9253c
1 changed files with 33 additions and 4 deletions
  1. 33 4
      examples/js/exporters/GLTFExporter.js

+ 33 - 4
examples/js/exporters/GLTFExporter.js

@@ -69,7 +69,8 @@ THREE.GLTFExporter.prototype = {
 			truncateDrawRange: true,
 			truncateDrawRange: true,
 			embedImages: true,
 			embedImages: true,
 			animations: [],
 			animations: [],
-			forceIndices: false
+			forceIndices: false,
+			forcePowerOfTwoTexture: false
 		};
 		};
 
 
 		options = Object.assign( {}, DEFAULT_OPTIONS, options );
 		options = Object.assign( {}, DEFAULT_OPTIONS, options );
@@ -192,6 +193,19 @@ THREE.GLTFExporter.prototype = {
 
 
 		}
 		}
 
 
+		/**
+		 * Checks if image size is POT.
+		 *
+		 * @param {Image} image The image to be checked.
+		 * @returns {Boolean} Returns true if image size is POT.
+		 *
+		 */
+		function isPowerOfTwo( image ) {
+
+			return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );
+
+		}
+
 		/**
 		/**
 		 * Get the required size + padding for a buffer, rounded to the next 4-byte boundary.
 		 * Get the required size + padding for a buffer, rounded to the next 4-byte boundary.
 		 * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
 		 * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
@@ -459,21 +473,36 @@ THREE.GLTFExporter.prototype = {
 			var mimeType = map.format === THREE.RGBAFormat ? 'image/png' : 'image/jpeg';
 			var mimeType = map.format === THREE.RGBAFormat ? 'image/png' : 'image/jpeg';
 			var gltfImage = { mimeType: mimeType };
 			var gltfImage = { mimeType: mimeType };
 
 
-			if ( options.embedImages ) {
+			if ( options.embedImages || ( options.forcePowerOfTwoTexture && ! isPowerOfTwo( map.image ) ) ) {
 
 
 				var canvas = cachedCanvas = cachedCanvas || document.createElement( 'canvas' );
 				var canvas = cachedCanvas = cachedCanvas || document.createElement( 'canvas' );
+
 				canvas.width = map.image.width;
 				canvas.width = map.image.width;
 				canvas.height = map.image.height;
 				canvas.height = map.image.height;
+
+				if ( options.forcePowerOfTwoTexture ) {
+
+					if ( ! options.embedImages ) {
+
+						console.warn( 'GLTFExporter: image is not power of two. Resized and embedded.', image );
+
+					}
+
+					canvas.width = THREE.Math.floorPowerOfTwo( canvas.width );
+					canvas.height = THREE.Math.floorPowerOfTwo( canvas.height );
+
+				}
+
 				var ctx = canvas.getContext( '2d' );
 				var ctx = canvas.getContext( '2d' );
 
 
 				if ( map.flipY === true ) {
 				if ( map.flipY === true ) {
 
 
-					ctx.translate( 0, map.image.height );
+					ctx.translate( 0, canvas.height );
 					ctx.scale( 1, - 1 );
 					ctx.scale( 1, - 1 );
 
 
 				}
 				}
 
 
-				ctx.drawImage( map.image, 0, 0 );
+				ctx.drawImage( map.image, 0, 0, canvas.width, canvas.height );
 
 
 				// @TODO Embed in { bufferView } if options.binary set.
 				// @TODO Embed in { bufferView } if options.binary set.