WebGL如何预加载图片并直接用于texImage2D纹理赋值操作
实现方案
核心思路
本质是提前完成所有图片资源的加载流程,将加载完成的资源存入全局缓存池,所有资源就绪后再执行业务逻辑,这样业务代码调用时直接取已加载完成的资源即可,无需等待onload回调。
具体实现代码
第一步:预加载逻辑封装
// 1. 定义需要预加载的所有图片路径 const preloadImageList = [ 'resource/1.png', // 其他需要预加载的图片都可添加到此处 ] // 2. 资源缓存池,key为图片路径,value为加载完成的Image对象 const imageCache = {} // 3. 单张图片加载的Promise封装 function loadImage(url) { return new Promise((resolve, reject) => { const img = new Image() // 如果是跨域图片需要添加下面这行配置 // img.crossOrigin = 'anonymous' img.onload = () => { imageCache[url] = img resolve(img) } img.onerror = (err) => reject(`图片加载失败:${url}, 错误信息:${err}`) img.src = url }) } // 4. 批量预加载所有资源,全部加载完成后再执行主业务逻辑 Promise.all(preloadImageList.map(url => loadImage(url))) .then(() => { console.log('所有图片预加载完成,启动主程序') main() }) .catch(err => console.error('预加载失败', err))
第二步:业务逻辑调用
此时直接从缓存池读取已完成加载的图片即可,不需要再处理onload回调:
function main() { // 直接从缓存池取已经加载完成的图片 const image = imageCache['resource/1.png'] // 直接调用WebGL纹理接口即可 gl.bindTexture(gl.TEXTURE_2D, texture) gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image) gl.generateMipmap(gl.TEXTURE_2D) }
可选方案:预存原始像素数据
如果需要直接使用二进制像素数据而非Image对象,可以在预加载阶段把图片绘制到离屏Canvas,提取像素数据缓存:
// 预加载时提取像素数据 function loadImageAndGetPixels(url) { return new Promise((resolve, reject) => { const img = new Image() img.onload = () => { const canvas = document.createElement('canvas') canvas.width = img.width canvas.height = img.height const ctx = canvas.getContext('2d') ctx.drawImage(img, 0, 0) const pixelData = ctx.getImageData(0, 0, img.width, img.height).data imageCache[url] = { data: pixelData, width: img.width, height: img.height } resolve() } img.onerror = reject img.src = url }) } // 调用时直接传像素数据 const imgInfo = imageCache['resource/1.png'] gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, imgInfo.width, imgInfo.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, imgInfo.data)
内容的提问来源于stack exchange,提问作者user16657004
相关产品推荐
相关产品推荐

