Compressed textures are able to upload to GPU

This commit is contained in:
Felipe Alfonso 2016-08-01 19:40:35 -04:00
parent 100aa413bf
commit 5ce4643dfa
4 changed files with 145 additions and 16 deletions

View file

@ -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)
{

View file

@ -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');

View file

@ -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)

View file

@ -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])