2024-10-25 18:09:59 +08:00

277 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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);
}
});
}
});
});