我正在使用WebGL开发一个浏览器游戏,建议的方法是使用普通的HTML元素或在WebGL画布上方覆盖一个2D画布来实现UI / HUD。虽然这很好,但是如何处理纹理共享呢?例如,在游戏中有掉落在地面上的物品,因此它们存在于世界中,并且必须作为WebGL纹理存在。
但是,当您拾取它们时,它们的图标将用作HUD中位置位于屏幕底部的能力栏中。因此,您必须有一个
目前,我通过两次加载纹理来解决这个问题,一次作为游戏中的WebGL纹理,一次作为画布纹理。但是我认为这种解决方案并不是非常可扩展,因为在最坏的情况下,我将不得不两次加载游戏中的每个纹理,这将使游戏的内存使用量翻倍。
以下是我加载纹理的两种方法供参考:
但是,当您拾取它们时,它们的图标将用作HUD中位置位于屏幕底部的能力栏中。因此,您必须有一个
Canvas2D
纹理以绘制UI,并有一个WebGLTexture
纹理以在WebGL画布上进行绘制。目前,我通过两次加载纹理来解决这个问题,一次作为游戏中的WebGL纹理,一次作为画布纹理。但是我认为这种解决方案并不是非常可扩展,因为在最坏的情况下,我将不得不两次加载游戏中的每个纹理,这将使游戏的内存使用量翻倍。
以下是我加载纹理的两种方法供参考:
// Load canvas texture
static createCanvasFromImage(filename: string) {
return new Promise((resolve, reject) => {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
let newImg = new Image();
newImg.onload = function() {
canvas.width = newImg.width;
canvas.height = newImg.height;
context.drawImage(newImg, 0, 0);
resolve(canvas);
}
newImg.src = filename;
});
}
.
// Load WebGL texture
static loadImageAndCreateTextureInfo(gl: WebGLRenderingContext, url: string) {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
// Fill the texture with a 1x1 blue pixel.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255]));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
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);
// Don't know size until it loads
var textureInfo = { width: 1, height: 1, texture: tex };
var img = new Image();
img.addEventListener('load', function() {
textureInfo.width = img.width;
textureInfo.height = img.height;
gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
});
img.src = url;
return textureInfo;
}
这种情况通常如何处理?有没有办法分享这些纹理,以便每个纹理只加载一次并且可以在任何画布上使用?
ctx.drawImage(textureCanvas, 0, 0)
在你的 Canvas 2D 中使用它,在 WebGL 中使用gl.texImage2D
。 - Georgi B. Nikolov