277 lines
10 KiB
JavaScript
277 lines
10 KiB
JavaScript
|
/* eslint-disable no-param-reassign */
|
|||
|
/* eslint-disable no-restricted-properties */
|
|||
|
/* eslint-disable no-plusplus */
|
|||
|
import canvasContext from './canvas-context';
|
|||
|
const downloadedTextures = {};
|
|||
|
const downloadingTextures = {};
|
|||
|
const downloadFailedTextures = {};
|
|||
|
let hasCheckSupportedExtensions = false;
|
|||
|
|
|||
|
if (typeof window !== 'undefined' && window.indexedDB) {
|
|||
|
Object.defineProperty(window, 'indexedDB', {
|
|||
|
get() {
|
|||
|
return undefined;
|
|||
|
},
|
|||
|
set() { },
|
|||
|
enumerable: true,
|
|||
|
configurable: true,
|
|||
|
});
|
|||
|
}
|
|||
|
const PotList = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096];
|
|||
|
const UseDXT5 = '$UseDXT5$';
|
|||
|
const pngPath = GameGlobal.unityNamespace.unityColorSpace && GameGlobal.unityNamespace.unityColorSpace === 'Linear' ? 'lpng' : 'png';
|
|||
|
let isStopDownloadTexture = false;
|
|||
|
const cachedDownloadTask = [];
|
|||
|
wx.stopDownloadTexture = function () {
|
|||
|
isStopDownloadTexture = true;
|
|||
|
};
|
|||
|
wx.starDownloadTexture = function () {
|
|||
|
isStopDownloadTexture = false;
|
|||
|
while (cachedDownloadTask.length > 0) {
|
|||
|
const task = cachedDownloadTask.shift();
|
|||
|
if (task) {
|
|||
|
mod.WXDownloadTexture(task.path, task.width, task.height, task.callback, task.limitType);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const mod = {
|
|||
|
getSupportedExtensions() {
|
|||
|
if (hasCheckSupportedExtensions) {
|
|||
|
return GameGlobal.TextureCompressedFormat;
|
|||
|
}
|
|||
|
const list = canvas
|
|||
|
.getContext(GameGlobal.managerConfig.contextConfig.contextType === 2 ? 'webgl2' : 'webgl')
|
|||
|
.getSupportedExtensions();
|
|||
|
const noneLimitSupportedTextures = ['']; // 兜底采用png
|
|||
|
GameGlobal.TextureCompressedFormat = '';
|
|||
|
if (list.indexOf('WEBGL_compressed_texture_s3tc') !== -1 && UseDXT5) {
|
|||
|
GameGlobal.TextureCompressedFormat = 'dds';
|
|||
|
}
|
|||
|
if (list.indexOf('WEBGL_compressed_texture_pvrtc') !== -1) {
|
|||
|
GameGlobal.TexturePVRTCSupported = true;
|
|||
|
GameGlobal.TextureCompressedFormat = 'pvr';
|
|||
|
}
|
|||
|
if (list.indexOf('WEBGL_compressed_texture_etc') !== -1) {
|
|||
|
GameGlobal.TextureEtc2Supported = true;
|
|||
|
noneLimitSupportedTextures.push('etc2');
|
|||
|
GameGlobal.TextureCompressedFormat = 'etc2';
|
|||
|
}
|
|||
|
if (list.indexOf('WEBGL_compressed_texture_astc') !== -1) {
|
|||
|
noneLimitSupportedTextures.push('astc');
|
|||
|
GameGlobal.TextureCompressedFormat = 'astc';
|
|||
|
}
|
|||
|
hasCheckSupportedExtensions = true;
|
|||
|
GameGlobal.NoneLimitSupportedTexture = noneLimitSupportedTextures.pop();
|
|||
|
return GameGlobal.TextureCompressedFormat;
|
|||
|
},
|
|||
|
getRemoteImageFile(path, width, height, limitType) {
|
|||
|
let textureFormat = GameGlobal.TextureCompressedFormat;
|
|||
|
if (textureFormat && limitType) {
|
|||
|
textureFormat = GameGlobal.NoneLimitSupportedTexture;
|
|||
|
}
|
|||
|
if (!textureFormat
|
|||
|
|| (textureFormat === 'pvr' && (width !== height || PotList.indexOf(width) === -1))
|
|||
|
|| (textureFormat === 'dds' && (width % 4 !== 0 || height % 4 !== 0))) {
|
|||
|
mod.downloadFile(path, width, height);
|
|||
|
}
|
|||
|
else {
|
|||
|
mod.requestFile(path, width, height, textureFormat, limitType);
|
|||
|
}
|
|||
|
},
|
|||
|
reTryRemoteImageFile(path, width, height, limitType = false) {
|
|||
|
const cid = path;
|
|||
|
if (!downloadFailedTextures[cid]) {
|
|||
|
downloadFailedTextures[cid] = {
|
|||
|
count: 0,
|
|||
|
path,
|
|||
|
width,
|
|||
|
height,
|
|||
|
limitType,
|
|||
|
};
|
|||
|
}
|
|||
|
if (downloadFailedTextures[cid].count > 4) {
|
|||
|
return;
|
|||
|
}
|
|||
|
setTimeout(() => {
|
|||
|
mod.getRemoteImageFile(path, width, height, limitType);
|
|||
|
}, Math.pow(2, downloadFailedTextures[cid].count) * 250);
|
|||
|
downloadFailedTextures[cid].count++;
|
|||
|
},
|
|||
|
requestFile(path, width, height, format, limitType) {
|
|||
|
const cid = path;
|
|||
|
const url = `${GameGlobal.manager.assetPath.replace(/\/$/, '')}/Textures/${format}/${width}/${path}.txt`;
|
|||
|
const xmlhttp = new GameGlobal.unityNamespace.UnityLoader.UnityCache.XMLHttpRequest();
|
|||
|
xmlhttp.responseType = 'arraybuffer';
|
|||
|
xmlhttp.open('GET', url, true);
|
|||
|
xmlhttp.onload = function () {
|
|||
|
const res = xmlhttp;
|
|||
|
if (res.status === 200) {
|
|||
|
downloadedTextures[cid] = {
|
|||
|
data: res.response,
|
|||
|
tmpFile: '',
|
|||
|
};
|
|||
|
downloadingTextures[cid].forEach(v => v());
|
|||
|
delete downloadingTextures[cid];
|
|||
|
delete downloadFailedTextures[cid];
|
|||
|
delete downloadedTextures[cid].data;
|
|||
|
}
|
|||
|
else {
|
|||
|
// err("压缩纹理下载失败!url:"+url);
|
|||
|
mod.reTryRemoteImageFile(path, width, height, limitType);
|
|||
|
}
|
|||
|
};
|
|||
|
xmlhttp.onerror = function () {
|
|||
|
// err("压缩纹理下载失败!url:"+url);
|
|||
|
mod.reTryRemoteImageFile(path, width, height, limitType);
|
|||
|
};
|
|||
|
xmlhttp.setRequestHeader('wechatminigame-skipclean', '1');
|
|||
|
xmlhttp.send(null);
|
|||
|
},
|
|||
|
callbackPngFile(path, cid) {
|
|||
|
const image = wx.createImage();
|
|||
|
image.crossOrigin = '';
|
|||
|
image.src = path;
|
|||
|
image.onload = function () {
|
|||
|
downloadedTextures[cid] = {
|
|||
|
data: image,
|
|||
|
tmpFile: '',
|
|||
|
};
|
|||
|
downloadingTextures[cid].forEach(v => v());
|
|||
|
delete downloadingTextures[cid];
|
|||
|
delete downloadFailedTextures[cid];
|
|||
|
delete downloadedTextures[cid];
|
|||
|
};
|
|||
|
},
|
|||
|
downloadFile(path, width, height) {
|
|||
|
const url = `${GameGlobal.manager.assetPath.replace(/\/$/, '')}/Textures/${pngPath}/${width}/${path}.png`;
|
|||
|
const cid = path;
|
|||
|
const cache = GameGlobal.manager.getCachePath(url);
|
|||
|
if (cache) {
|
|||
|
mod.callbackPngFile(cache, cid);
|
|||
|
}
|
|||
|
else {
|
|||
|
if (GameGlobal.unityNamespace.needCacheTextures) {
|
|||
|
const xmlhttp = new GameGlobal.unityNamespace.UnityLoader.UnityCache.XMLHttpRequest();
|
|||
|
xmlhttp.responseType = 'arraybuffer';
|
|||
|
xmlhttp.open('GET', url, true);
|
|||
|
xmlhttp.onsave = function (path) {
|
|||
|
mod.callbackPngFile(path, cid);
|
|||
|
};
|
|||
|
xmlhttp.onerror = function () {
|
|||
|
mod.reTryRemoteImageFile(path, width, height);
|
|||
|
};
|
|||
|
xmlhttp.setRequestHeader('wechatminigame-skipclean', '1');
|
|||
|
xmlhttp.send(null);
|
|||
|
}
|
|||
|
else {
|
|||
|
const image = wx.createImage();
|
|||
|
image.crossOrigin = '';
|
|||
|
image.src = url;
|
|||
|
image.onload = function () {
|
|||
|
downloadedTextures[cid] = {
|
|||
|
data: image,
|
|||
|
tmpFile: '',
|
|||
|
};
|
|||
|
downloadingTextures[cid].forEach(v => v());
|
|||
|
delete downloadingTextures[cid];
|
|||
|
delete downloadFailedTextures[cid];
|
|||
|
delete downloadedTextures[cid];
|
|||
|
};
|
|||
|
image.onerror = function () {
|
|||
|
mod.reTryRemoteImageFile(path, width, height);
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
WXDownloadTexture(path, width, height, callback, limitType = false) {
|
|||
|
const width4m = width % 4;
|
|||
|
if (width4m !== 0) {
|
|||
|
width += 4 - width4m;
|
|||
|
}
|
|||
|
if (!hasCheckSupportedExtensions) {
|
|||
|
mod.getSupportedExtensions();
|
|||
|
}
|
|||
|
const cid = path;
|
|||
|
if (!cid) { // 可能由于瘦身资源发起的下载此处将直接忽略
|
|||
|
return;
|
|||
|
}
|
|||
|
/*
|
|||
|
if(downloadedTextures[cid]){
|
|||
|
if(downloadedTextures[cid].data){
|
|||
|
callback();
|
|||
|
}else{
|
|||
|
mod.readFile(id,type,callback,width,height);
|
|||
|
}
|
|||
|
}else */
|
|||
|
if (isStopDownloadTexture) {
|
|||
|
cachedDownloadTask.push({
|
|||
|
path,
|
|||
|
width,
|
|||
|
height,
|
|||
|
callback,
|
|||
|
limitType,
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
if (downloadingTextures[cid]) {
|
|||
|
downloadingTextures[cid].push(callback);
|
|||
|
}
|
|||
|
else {
|
|||
|
downloadingTextures[cid] = [callback];
|
|||
|
mod.getRemoteImageFile(path, width, height, limitType);
|
|||
|
}
|
|||
|
},
|
|||
|
};
|
|||
|
GameGlobal.DownloadedTextures = downloadedTextures;
|
|||
|
GameGlobal.TextureCompressedFormat = ''; // 支持的压缩格式
|
|||
|
GameGlobal.ParalleLDownloadTexture = function (filename) {
|
|||
|
filename = filename.replace(GameGlobal.managerConfig.DATA_CDN, '').replace(/^\//, '');
|
|||
|
filename = `/${filename}`;
|
|||
|
if (GameGlobal.TEXTURE_BUNDLES[filename]) {
|
|||
|
GameGlobal.TEXTURE_BUNDLES[filename].forEach((v) => {
|
|||
|
const f = GameGlobal.TextureCompressedFormat;
|
|||
|
if (!f) {
|
|||
|
const p = `${GameGlobal.manager.assetPath}/Textures/png/${v.w}/${v.p}.png`;
|
|||
|
const image = wx.createImage();
|
|||
|
image.crossOrigin = '';
|
|||
|
image.src = p;
|
|||
|
}
|
|||
|
else if (f !== 'pvr') {
|
|||
|
const http = new GameGlobal.unityNamespace.UnityLoader.UnityCache.XMLHttpRequest();
|
|||
|
const p = `${GameGlobal.manager.assetPath}/Textures/${f}/${v.w}/${v.p}.txt`;
|
|||
|
http.open('GET', p, true);
|
|||
|
http.responseType = 'arraybuffer';
|
|||
|
http.setRequestHeader('wechatminigame-skipclean', '1');
|
|||
|
http.send();
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
};
|
|||
|
export default {
|
|||
|
WXDownloadTexture: mod.WXDownloadTexture,
|
|||
|
};
|
|||
|
canvasContext.addCreatedListener(() => {
|
|||
|
if (GameGlobal.USED_TEXTURE_COMPRESSION) {
|
|||
|
mod.getSupportedExtensions();
|
|||
|
if (GameGlobal.TextureCompressedFormat === '' || GameGlobal.TextureCompressedFormat === 'pvr') {
|
|||
|
const { platform } = wx.getDeviceInfo();
|
|||
|
if (platform === 'ios') {
|
|||
|
wx.showModal({
|
|||
|
title: '提示',
|
|||
|
content: '当前操作系统版本过低,建议您升级至最新版本。',
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
wx.onNetworkStatusChange((res) => {
|
|||
|
if (res.isConnected) {
|
|||
|
Object.keys(downloadFailedTextures).forEach((key) => {
|
|||
|
const v = downloadFailedTextures[key];
|
|||
|
if (v.count > 4) {
|
|||
|
mod.getRemoteImageFile(v.path, v.width, v.height, v.limitType);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
});
|
|||
|
});
|