277 lines
10 KiB
JavaScript
Raw Normal View History

2024-10-25 18:09:59 +08:00
/* eslint-disable no-param-reassign */
/* eslint-disable no-restricted-properties */
/* eslint-disable no-plusplus */
2024-10-23 09:14:01 +08:00
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') {
2024-10-25 18:09:59 +08:00
const { platform } = wx.getDeviceInfo();
if (platform === 'ios') {
wx.showModal({
title: '提示',
content: '当前操作系统版本过低,建议您升级至最新版本。',
});
}
2024-10-23 09:14:01 +08:00
}
}
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);
}
});
}
});
});