diff --git a/src/loader/Cache.js b/src/loader/Cache.js index 215f596fb..19e4083e8 100644 --- a/src/loader/Cache.js +++ b/src/loader/Cache.js @@ -236,13 +236,35 @@ Phaser.Cache.prototype = { ////////////////// addCompressedTextureMetaData: function (key, url, extension, arrayBuffer) { + //TODO: Check if texture was loaded and remove it was var data = (extension in Phaser.LoaderParser) ? Phaser.LoaderParser[extension](arrayBuffer) : arrayBuffer; - this._cache.compressedTexture[key] = { - data: data, - url: url, + + var texture = { key: key, + url: url, + data: data, + base: new PIXI.BaseTexture(data), + frame: new Phaser.Frame(0, 0, 0, data.width, data.height, key), + frameData: new Phaser.FrameData(), fileFormat: extension }; + + texture.frameData.addFrame(new Phaser.Frame(0, 0, 0, data.width, data.height, url)); + + this._cache.compressedTexture[key] = texture; + + this._resolveURL(url, texture); + + if (key === '__default') + { + Phaser.Cache.DEFAULT = new PIXI.Texture(img.base); + } + else if (key === '__missing') + { + Phaser.Cache.MISSING = new PIXI.Texture(img.base); + } + + return texture; }, /** @@ -1118,7 +1140,15 @@ Phaser.Cache.prototype = { if (full === undefined) { full = false; } - var img = this.getItem(key, Phaser.Cache.IMAGE, 'getImage'); + var img = null; + + if (key in this._cacheMap[Phaser.Cache.COMPRESSED_TEXTURE]) + img = this.getItem(key, Phaser.Cache.COMPRESSED_TEXTURE, 'getImage'); + + if (img === null) + { + img = this.getItem(key, Phaser.Cache.IMAGE, 'getImage'); + } if (img === null) { diff --git a/src/loader/Loader.js b/src/loader/Loader.js index fe1888dde..e5972597b 100644 --- a/src/loader/Loader.js +++ b/src/loader/Loader.js @@ -723,7 +723,7 @@ Phaser.Loader.prototype = { var compression = this.game.renderer.extensions.compression, exkey; if (this.game.renderType === Phaser.WEBGL) { for (exkey in object) { - if (exkey in compression) { + if (exkey.toUpperCase() in compression) { this.addToFileList('texture', key + '_' + exkey, object[exkey], undefined, overwrite, '.pvr'); } else if (exkey === 'truecolor') { this.addToFileList('texture', key + '_' + exkey, object[exkey], undefined, overwrite, '.png'); diff --git a/src/loader/LoaderParser.js b/src/loader/LoaderParser.js index 83f9240ec..58419205a 100644 --- a/src/loader/LoaderParser.js +++ b/src/loader/LoaderParser.js @@ -193,7 +193,8 @@ Phaser.LoaderParser = { byteArray = new Uint8Array(arrayBuffer), pvrHeader = null, pixelFormat = (uintArray[3] << 32 | uintArray[2]), - compressionAlgorithm; + compressionAlgorithm, + glExtensionFormat = 0; if (uintArray[0] === 0x03525650 && [ // Validate WebGL Pixel Format @@ -208,7 +209,36 @@ Phaser.LoaderParser = { } else if (pixelFormat == 6) { compressionAlgorithm = 'ETC1'; } + switch (pixelFormat) { + case 0: + glExtensionFormat = 0x8C01; + break; + case 1: + glExtensionFormat = 0x8C03; + break; + case 2: + glExtensionFormat = 0x8C00; + break; + case 3: + glExtensionFormat = 0x8C02; + break; + case 6: + glExtensionFormat = 0x8D64; + break; + case 7: + glExtensionFormat = 0x83F1; + break; + case 9: + glExtensionFormat = 0x83F2; + break; + case 11: + glExtensionFormat = 0x83F3; + break; + default: + glExtensionFormat = -1; + } pvrHeader = { + complete: true, fileFormat: 'PVR', compressionAlgorithm: compressionAlgorithm, flags: uintArray[1], @@ -222,7 +252,8 @@ Phaser.LoaderParser = { numberOfFaces: uintArray[10], numberOfMipmaps: uintArray[11], metaDataSize: uintArray[12], - textureData: byteArray.subarray(52 + uintArray[12], byteArray.byteLength) + textureData: byteArray.subarray(52 + uintArray[12], byteArray.byteLength), + glExtensionFormat: glExtensionFormat }; } return pvrHeader; @@ -277,6 +308,7 @@ Phaser.LoaderParser = { byteArray[2] === 0x53 && byteArray[3] === 0x20) { ddsHeader = { + complete: true, fileFormat: 'DDS', compressionAlgorithm: 'S3TC', size: uintArray[1], @@ -392,6 +424,7 @@ Phaser.LoaderParser = { break; } ktxHeader = { + complete: true, fileFormat: 'KTX', compressionAlgorithm: compressionAlgorithm, endianness: uintArray[3], @@ -400,8 +433,8 @@ Phaser.LoaderParser = { glFormat: uintArray[6], glInternalFormat: uintArray[7], glBaseInternalFormat: uintArray[8], - pixelWidth: uintArray[9], - pixelHeight: uintArray[10], + width: uintArray[9], + height: uintArray[10], pixelDepth: uintArray[11], numberOfArrayElements: uintArray[12], numberOfFaces: uintArray[13], @@ -442,11 +475,12 @@ Phaser.LoaderParser = { byteArray[2] === 0x4D && byteArray[3] === 0x20) { pkmHeader = { + complete: true, fileFormat: 'PKM', compressionAlgorithm: 'ETC1', format: ((byteArray[6] << 8 | byteArray[7])) & 0xFFFF, - extendedWidth: ((byteArray[8] << 8 | byteArray[9])) & 0xFFFF, - extendedHeight: ((byteArray[10] << 8 | byteArray[11])) & 0xFFFF, + width: ((byteArray[8] << 8 | byteArray[9])) & 0xFFFF, + height: ((byteArray[10] << 8 | byteArray[11])) & 0xFFFF, originalWidth: ((byteArray[12] << 8 | byteArray[13])) & 0xFFFF, originalHeight: ((byteArray[14] << 8 | byteArray[15])) & 0xFFFF, textureData: byteArray.subarray(16, byteArray.length) diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index 01ee2b5c3..842658ca6 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -251,9 +251,9 @@ PIXI.WebGLRenderer.prototype.initContext = function() pvrtc = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'); s3tc = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc'); - if (etc1) this.extensions.compression.etc1 = etc1; - if (pvrtc) this.extensions.compression.pvrtc = pvrtc; - if (s3tc) this.extensions.compression.s3tc = s3tc; + if (etc1) this.extensions.compression.ETC1 = etc1; + if (pvrtc) this.extensions.compression.PVRTC = pvrtc; + if (s3tc) this.extensions.compression.S3TC = s3tc; }; PIXI.WebGLRenderer.prototype.setTexturePriority = function (textureNameCollection) { @@ -392,6 +392,70 @@ PIXI.WebGLRenderer.prototype.resize = function (width, height) { }; +/** + * Updates and creates a WebGL compressed texture for the renderers context. + * + * @method updateTexture + * @param texture {Texture} the texture to update + * @return {boolean} True if the texture was successfully bound, otherwise false. + */ +PIXI.WebGLRenderer.prototype.updateCompressedTexture = function (texture) { + if (!texture.hasLoaded) + { + return false; + } + var gl = this.gl; + var textureMetaData = texture.source; + + if (!texture._glTextures[gl.id]) + { + texture._glTextures[gl.id] = gl.createTexture(); + } + gl.activeTexture(gl.TEXTURE0 + texture.textureIndex); + + gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]); + + + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultipliedAlpha); + + gl.compressedTexImage2D( + gl.TEXTURE_2D, + 0, + textureMetaData.glExtensionFormat, + textureMetaData.width, + textureMetaData.height, + 0, + textureMetaData.textureData + ); + + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); + + if (texture.mipmap && PIXI.isPowerOfTwo(texture.width, texture.height)) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); + gl.generateMipmap(gl.TEXTURE_2D); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); + } + + if (!texture._powerOf2) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + } + + texture._dirty[gl.id] = false; + + return true; +}; + /** * Updates and creates a WebGL texture for the renderers context. * @@ -400,12 +464,13 @@ PIXI.WebGLRenderer.prototype.resize = function (width, height) { * @return {boolean} True if the texture was successfully bound, otherwise false. */ PIXI.WebGLRenderer.prototype.updateTexture = function (texture) { - if (!texture.hasLoaded) { return false; } - + if (texture.source.compressionAlgorithm) { + return this.updateCompressedTexture(texture); + } var gl = this.gl; if (!texture._glTextures[gl.id])