mirror of
https://github.com/photonstorm/phaser
synced 2025-02-25 20:07:08 +00:00
Compressed textures are able to upload to GPU
This commit is contained in:
parent
100aa413bf
commit
5ce4643dfa
4 changed files with 145 additions and 16 deletions
|
@ -236,13 +236,35 @@ Phaser.Cache.prototype = {
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
addCompressedTextureMetaData: function (key, url, extension, arrayBuffer) {
|
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;
|
var data = (extension in Phaser.LoaderParser) ? Phaser.LoaderParser[extension](arrayBuffer) : arrayBuffer;
|
||||||
this._cache.compressedTexture[key] = {
|
|
||||||
data: data,
|
var texture = {
|
||||||
url: url,
|
|
||||||
key: key,
|
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
|
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; }
|
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)
|
if (img === null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -723,7 +723,7 @@ Phaser.Loader.prototype = {
|
||||||
var compression = this.game.renderer.extensions.compression, exkey;
|
var compression = this.game.renderer.extensions.compression, exkey;
|
||||||
if (this.game.renderType === Phaser.WEBGL) {
|
if (this.game.renderType === Phaser.WEBGL) {
|
||||||
for (exkey in object) {
|
for (exkey in object) {
|
||||||
if (exkey in compression) {
|
if (exkey.toUpperCase() in compression) {
|
||||||
this.addToFileList('texture', key + '_' + exkey, object[exkey], undefined, overwrite, '.pvr');
|
this.addToFileList('texture', key + '_' + exkey, object[exkey], undefined, overwrite, '.pvr');
|
||||||
} else if (exkey === 'truecolor') {
|
} else if (exkey === 'truecolor') {
|
||||||
this.addToFileList('texture', key + '_' + exkey, object[exkey], undefined, overwrite, '.png');
|
this.addToFileList('texture', key + '_' + exkey, object[exkey], undefined, overwrite, '.png');
|
||||||
|
|
|
@ -193,7 +193,8 @@ Phaser.LoaderParser = {
|
||||||
byteArray = new Uint8Array(arrayBuffer),
|
byteArray = new Uint8Array(arrayBuffer),
|
||||||
pvrHeader = null,
|
pvrHeader = null,
|
||||||
pixelFormat = (uintArray[3] << 32 | uintArray[2]),
|
pixelFormat = (uintArray[3] << 32 | uintArray[2]),
|
||||||
compressionAlgorithm;
|
compressionAlgorithm,
|
||||||
|
glExtensionFormat = 0;
|
||||||
|
|
||||||
if (uintArray[0] === 0x03525650 &&
|
if (uintArray[0] === 0x03525650 &&
|
||||||
[ // Validate WebGL Pixel Format
|
[ // Validate WebGL Pixel Format
|
||||||
|
@ -208,7 +209,36 @@ Phaser.LoaderParser = {
|
||||||
} else if (pixelFormat == 6) {
|
} else if (pixelFormat == 6) {
|
||||||
compressionAlgorithm = 'ETC1';
|
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 = {
|
pvrHeader = {
|
||||||
|
complete: true,
|
||||||
fileFormat: 'PVR',
|
fileFormat: 'PVR',
|
||||||
compressionAlgorithm: compressionAlgorithm,
|
compressionAlgorithm: compressionAlgorithm,
|
||||||
flags: uintArray[1],
|
flags: uintArray[1],
|
||||||
|
@ -222,7 +252,8 @@ Phaser.LoaderParser = {
|
||||||
numberOfFaces: uintArray[10],
|
numberOfFaces: uintArray[10],
|
||||||
numberOfMipmaps: uintArray[11],
|
numberOfMipmaps: uintArray[11],
|
||||||
metaDataSize: uintArray[12],
|
metaDataSize: uintArray[12],
|
||||||
textureData: byteArray.subarray(52 + uintArray[12], byteArray.byteLength)
|
textureData: byteArray.subarray(52 + uintArray[12], byteArray.byteLength),
|
||||||
|
glExtensionFormat: glExtensionFormat
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return pvrHeader;
|
return pvrHeader;
|
||||||
|
@ -277,6 +308,7 @@ Phaser.LoaderParser = {
|
||||||
byteArray[2] === 0x53 &&
|
byteArray[2] === 0x53 &&
|
||||||
byteArray[3] === 0x20) {
|
byteArray[3] === 0x20) {
|
||||||
ddsHeader = {
|
ddsHeader = {
|
||||||
|
complete: true,
|
||||||
fileFormat: 'DDS',
|
fileFormat: 'DDS',
|
||||||
compressionAlgorithm: 'S3TC',
|
compressionAlgorithm: 'S3TC',
|
||||||
size: uintArray[1],
|
size: uintArray[1],
|
||||||
|
@ -392,6 +424,7 @@ Phaser.LoaderParser = {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ktxHeader = {
|
ktxHeader = {
|
||||||
|
complete: true,
|
||||||
fileFormat: 'KTX',
|
fileFormat: 'KTX',
|
||||||
compressionAlgorithm: compressionAlgorithm,
|
compressionAlgorithm: compressionAlgorithm,
|
||||||
endianness: uintArray[3],
|
endianness: uintArray[3],
|
||||||
|
@ -400,8 +433,8 @@ Phaser.LoaderParser = {
|
||||||
glFormat: uintArray[6],
|
glFormat: uintArray[6],
|
||||||
glInternalFormat: uintArray[7],
|
glInternalFormat: uintArray[7],
|
||||||
glBaseInternalFormat: uintArray[8],
|
glBaseInternalFormat: uintArray[8],
|
||||||
pixelWidth: uintArray[9],
|
width: uintArray[9],
|
||||||
pixelHeight: uintArray[10],
|
height: uintArray[10],
|
||||||
pixelDepth: uintArray[11],
|
pixelDepth: uintArray[11],
|
||||||
numberOfArrayElements: uintArray[12],
|
numberOfArrayElements: uintArray[12],
|
||||||
numberOfFaces: uintArray[13],
|
numberOfFaces: uintArray[13],
|
||||||
|
@ -442,11 +475,12 @@ Phaser.LoaderParser = {
|
||||||
byteArray[2] === 0x4D &&
|
byteArray[2] === 0x4D &&
|
||||||
byteArray[3] === 0x20) {
|
byteArray[3] === 0x20) {
|
||||||
pkmHeader = {
|
pkmHeader = {
|
||||||
|
complete: true,
|
||||||
fileFormat: 'PKM',
|
fileFormat: 'PKM',
|
||||||
compressionAlgorithm: 'ETC1',
|
compressionAlgorithm: 'ETC1',
|
||||||
format: ((byteArray[6] << 8 | byteArray[7])) & 0xFFFF,
|
format: ((byteArray[6] << 8 | byteArray[7])) & 0xFFFF,
|
||||||
extendedWidth: ((byteArray[8] << 8 | byteArray[9])) & 0xFFFF,
|
width: ((byteArray[8] << 8 | byteArray[9])) & 0xFFFF,
|
||||||
extendedHeight: ((byteArray[10] << 8 | byteArray[11])) & 0xFFFF,
|
height: ((byteArray[10] << 8 | byteArray[11])) & 0xFFFF,
|
||||||
originalWidth: ((byteArray[12] << 8 | byteArray[13])) & 0xFFFF,
|
originalWidth: ((byteArray[12] << 8 | byteArray[13])) & 0xFFFF,
|
||||||
originalHeight: ((byteArray[14] << 8 | byteArray[15])) & 0xFFFF,
|
originalHeight: ((byteArray[14] << 8 | byteArray[15])) & 0xFFFF,
|
||||||
textureData: byteArray.subarray(16, byteArray.length)
|
textureData: byteArray.subarray(16, byteArray.length)
|
||||||
|
|
|
@ -251,9 +251,9 @@ PIXI.WebGLRenderer.prototype.initContext = function()
|
||||||
pvrtc = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');
|
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');
|
s3tc = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc');
|
||||||
|
|
||||||
if (etc1) this.extensions.compression.etc1 = etc1;
|
if (etc1) this.extensions.compression.ETC1 = etc1;
|
||||||
if (pvrtc) this.extensions.compression.pvrtc = pvrtc;
|
if (pvrtc) this.extensions.compression.PVRTC = pvrtc;
|
||||||
if (s3tc) this.extensions.compression.s3tc = s3tc;
|
if (s3tc) this.extensions.compression.S3TC = s3tc;
|
||||||
};
|
};
|
||||||
|
|
||||||
PIXI.WebGLRenderer.prototype.setTexturePriority = function (textureNameCollection) {
|
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.
|
* 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.
|
* @return {boolean} True if the texture was successfully bound, otherwise false.
|
||||||
*/
|
*/
|
||||||
PIXI.WebGLRenderer.prototype.updateTexture = function (texture) {
|
PIXI.WebGLRenderer.prototype.updateTexture = function (texture) {
|
||||||
|
|
||||||
if (!texture.hasLoaded)
|
if (!texture.hasLoaded)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (texture.source.compressionAlgorithm) {
|
||||||
|
return this.updateCompressedTexture(texture);
|
||||||
|
}
|
||||||
var gl = this.gl;
|
var gl = this.gl;
|
||||||
|
|
||||||
if (!texture._glTextures[gl.id])
|
if (!texture._glTextures[gl.id])
|
||||||
|
|
Loading…
Add table
Reference in a new issue