205 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| import response from './response';
 | |
| import moduleHelper from './module-helper';
 | |
| import { getDefaultData, debugLog } from './utils';
 | |
| import { isSupportSharedCanvasMode } from '../check-version';
 | |
| 
 | |
| let cachedOpenDataContext;
 | |
| let cachedSharedCanvas;
 | |
| var SharedCanvasMode;
 | |
| (function (SharedCanvasMode) {
 | |
|     SharedCanvasMode["ScreenCanvas"] = "screenCanvas";
 | |
|     SharedCanvasMode["OffScreenCanvas"] = "offscreenCanvas";
 | |
| })(SharedCanvasMode || (SharedCanvasMode = {}));
 | |
| let sharedCanvasMode;
 | |
| let timerId;
 | |
| let textureObject = null;
 | |
| let textureId;
 | |
| 
 | |
| function getOpenDataContext(mode) {
 | |
|     if (cachedOpenDataContext) {
 | |
|         return cachedOpenDataContext;
 | |
|     }
 | |
|     
 | |
|     if (!isSupportSharedCanvasMode) {
 | |
|         if (mode === 'ScreenCanvas') {
 | |
|             console.warn('[unity-sdk]: 当前环境不支持 ScreenCanvas 模式');
 | |
|         }
 | |
|         sharedCanvasMode = SharedCanvasMode.OffScreenCanvas;
 | |
|     }
 | |
|     
 | |
|     if (!sharedCanvasMode) {
 | |
|         if (typeof mode === 'string' && SharedCanvasMode[mode]) {
 | |
|             sharedCanvasMode = SharedCanvasMode[mode];
 | |
|         }
 | |
|         else {
 | |
|             sharedCanvasMode = SharedCanvasMode.OffScreenCanvas;
 | |
|         }
 | |
|     }
 | |
|     console.log(`[unity-sdk]: 当前开放数据域为 ${sharedCanvasMode} 模式`);
 | |
|     // @ts-ignore
 | |
|     cachedOpenDataContext = wx.getOpenDataContext({
 | |
|         sharedCanvasMode,
 | |
|     });
 | |
|     return cachedOpenDataContext;
 | |
| }
 | |
| 
 | |
| function getSharedCanvas() {
 | |
|     return cachedSharedCanvas || getOpenDataContext().canvas;
 | |
| }
 | |
| 
 | |
| function hookUnityRender() {
 | |
|     if (!textureId) {
 | |
|         return;
 | |
|     }
 | |
|     const { GL } = GameGlobal.manager.gameInstance.Module;
 | |
|     const gl = GL.currentContext.GLctx;
 | |
|     if (!textureObject) {
 | |
|         textureObject = gl.createTexture();
 | |
|         gl.bindTexture(gl.TEXTURE_2D, textureObject);
 | |
|         if (GameGlobal.unityNamespace.unityColorSpace === 'Linear') {
 | |
|             gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, gl.RGBA, gl.UNSIGNED_BYTE, getSharedCanvas());
 | |
|         }
 | |
|         else {
 | |
|             gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, getSharedCanvas());
 | |
|         }
 | |
|         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
 | |
|         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
 | |
|         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.bindTexture(gl.TEXTURE_2D, textureObject);
 | |
|         if (GameGlobal.unityNamespace.unityColorSpace === 'Linear') {
 | |
|             gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, gl.RGBA, gl.UNSIGNED_BYTE, getSharedCanvas());
 | |
|         }
 | |
|         else {
 | |
|             gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, getSharedCanvas());
 | |
|         }
 | |
|     }
 | |
|     GL.textures[textureId] = textureObject;
 | |
|     timerId = requestAnimationFrame(hookUnityRender);
 | |
| }
 | |
| 
 | |
| function stopLastRenderLoop() {
 | |
|     
 | |
|     if (typeof timerId !== 'undefined') {
 | |
|         cancelAnimationFrame(timerId);
 | |
|     }
 | |
| }
 | |
| function startHookUnityRender() {
 | |
|     stopLastRenderLoop();
 | |
|     hookUnityRender();
 | |
| }
 | |
| function stopHookUnityRender() {
 | |
|     stopLastRenderLoop();
 | |
|     
 | |
|     const sharedCanvas = getSharedCanvas();
 | |
|     sharedCanvas.width = 1;
 | |
|     sharedCanvas.height = 1;
 | |
|     
 | |
|     const { GL } = GameGlobal.manager.gameInstance.Module;
 | |
|     const gl = GL.currentContext.GLctx;
 | |
|     gl.deleteTexture(textureObject);
 | |
|     textureObject = null;
 | |
| }
 | |
| wx.onShow(() => {
 | |
|     if (cachedOpenDataContext) {
 | |
|         getOpenDataContext().postMessage({
 | |
|             type: 'WXShow',
 | |
|         });
 | |
|     }
 | |
| });
 | |
| export default {
 | |
|     WXGetOpenDataContext(mode) {
 | |
|         debugLog('WXGetOpenDataContext:', mode);
 | |
|         getOpenDataContext(mode);
 | |
|     },
 | |
|     WXDataContextPostMessage(msg) {
 | |
|         debugLog('WXDataContextPostMessage:', msg);
 | |
|         getOpenDataContext().postMessage(msg);
 | |
|     },
 | |
|     WXShowOpenData(id, x, y, width, height) {
 | |
|         debugLog('WXShowOpenData:', id, x, y, width, height);
 | |
|         if (width <= 0 || height <= 0) {
 | |
|             console.error('[unity-sdk]: WXShowOpenData要求 width 和 height 参数必须大于0');
 | |
|         }
 | |
|         
 | |
|         if (!cachedOpenDataContext) {
 | |
|             console.warn('[unity-sdk]: 请先调用 WXGetOpenDataContext');
 | |
|         }
 | |
|         
 | |
|         const openDataContext = getOpenDataContext();
 | |
|         const sharedCanvas = openDataContext.canvas;
 | |
|         sharedCanvas.width = width;
 | |
|         sharedCanvas.height = height;
 | |
|         if (sharedCanvasMode === SharedCanvasMode.ScreenCanvas && sharedCanvas.style) {
 | |
|             sharedCanvas.style.left = `${x / window.devicePixelRatio}px`;
 | |
|             sharedCanvas.style.top = `${y / window.devicePixelRatio}px`;
 | |
|             sharedCanvas.style.width = `${width / window.devicePixelRatio}px`;
 | |
|             sharedCanvas.style.height = `${height / window.devicePixelRatio}px`;
 | |
|         }
 | |
|         openDataContext.postMessage({
 | |
|             type: 'WXRender',
 | |
|             x,
 | |
|             y,
 | |
|             width,
 | |
|             height,
 | |
|             devicePixelRatio: window.devicePixelRatio,
 | |
|         });
 | |
|         if (sharedCanvasMode === SharedCanvasMode.OffScreenCanvas) {
 | |
|             textureId = id;
 | |
|             startHookUnityRender();
 | |
|         }
 | |
|     },
 | |
|     WXHideOpenData() {
 | |
|         debugLog('WXHideOpenData');
 | |
|         if (!cachedOpenDataContext) {
 | |
|             console.warn('[unity-sdk]: 请先调用 WXGetOpenDataContext');
 | |
|             return;
 | |
|         }
 | |
|         getOpenDataContext().postMessage({
 | |
|             type: 'WXDestroy',
 | |
|         });
 | |
|         if (sharedCanvasMode === SharedCanvasMode.OffScreenCanvas) {
 | |
|             stopHookUnityRender();
 | |
|         }
 | |
|         else if (sharedCanvasMode === SharedCanvasMode.ScreenCanvas) {
 | |
|             const sharedCanvas = getSharedCanvas();
 | |
|             if (sharedCanvas.style) {
 | |
|                 sharedCanvas.style.top = '9999px';
 | |
|             }
 | |
|         }
 | |
|     },
 | |
|     WXOpenDataToTempFilePathSync(conf) {
 | |
|         debugLog('WXOpenDataToTempFilePathSync', conf);
 | |
|         const sharedCanvas = getSharedCanvas();
 | |
|         if (!sharedCanvas) {
 | |
|             return 'Please use WX.GetOpenDataContext() first';
 | |
|         }
 | |
|         return sharedCanvas.toTempFilePathSync(getDefaultData(sharedCanvas, conf));
 | |
|     },
 | |
|     WXOpenDataToTempFilePath(conf, s, f, c) {
 | |
|         debugLog('WXOpenDataToTempFilePath', conf);
 | |
|         if (conf) {
 | |
|             const sharedCanvas = getSharedCanvas();
 | |
|             if (!sharedCanvas) {
 | |
|                 console.error('Please use WX.GetOpenDataContext() first');
 | |
|                 return;
 | |
|             }
 | |
|             sharedCanvas.toTempFilePath({
 | |
|                 ...getDefaultData(sharedCanvas, conf),
 | |
|                 ...response.handleText(s, f, c),
 | |
|                 success: (res) => {
 | |
|                     moduleHelper.send('ToTempFilePathCallback', JSON.stringify({
 | |
|                         callbackId: s,
 | |
|                         errMsg: res.errMsg,
 | |
|                         errCode: res.errCode || 0,
 | |
|                         tempFilePath: res.tempFilePath,
 | |
|                     }));
 | |
|                 },
 | |
|             });
 | |
|         }
 | |
|     },
 | |
| };
 |