【问题标题】:Loading an image using the Fetch API for use with WebGL使用 Fetch API 加载图像以用于 WebGL
【发布时间】:2022-11-06 18:45:04
【问题描述】:

我想加载没有像.onload() 这样的回调的纹理。我正在尝试使用 blob 中的纹理:https://plnkr.co/edit/n4CbWMEOAyJMQFYy

    const response = await fetch("./assets/texture.png");
    const imageBlob = await response.blob();
    const imageBitmap = await createImageBitmap(imageBlob);
    console.log(imageBitmap);

    const texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, imageBitmap);

预期结果是:

但我有这个:

我可以在Network 选项卡中看到图片已上传:

这行代码console.log(imageBitmap); 表示图像存在:

texImage2D() documentation 说我可以使用 ImageBitmap 作为源。

更新

我尝试使用此答案中的loadImage 函数:https://stackoverflow.com/a/52060802/4159530 Playground:https://plnkr.co/edit/n4CbWMEOAyJMQFYy

function loadImage(url) {
    return new Promise(resolve => {
        const image = new Image();
        image.addEventListener('load', () => {
            resolve(image);
        });
        image.src = url;
    });
}

/* ... */

async function init() {
/* ... */

    const image = await loadImage("./assets/texture.png");
    const texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);

/* ... */
}

但这并没有解决问题。

【问题讨论】:

  • 我没有使用response.blob() 机制,但我使用Image() 已经成功。可以看看stackoverflow.com/a/52060802/691711吗?也许 blob 的形成方式会导致问题。我认为Image() 也可能会处理编码,但我可能会在那里做出假设。
  • 不幸的是loadImage() 不起作用:const image = await loadImage("./assets/texture.png");
  • @ zero298 我在帖子中添加了我根据您的建议尝试过的内容。
  • @zero298 你可以在 Playground 上试试:plnkr.co/edit/n4CbWMEOAyJMQFYy
  • @zero298 现在可以了!我在gl.texImage2D 之后添加了draw();plnkr.co/edit/n4CbWMEOAyJMQFYy 但我不明白为什么会跳过这个draw() 函数:function main() { if (!init()) return; draw(); }

标签: javascript webgl


【解决方案1】:

这个答案帮助我解决了这个问题:https://stackoverflow.com/a/52060802/4159530

游乐场:https://plnkr.co/edit/n4CbWMEOAyJMQFYy

function loadImage(url) {
    return new Promise(resolve => {
        const image = new Image();
        image.addEventListener("load", () => {
            resolve(image);
        });
        image.src = url;
    });
}

/* ... */

async function init() {
/* ... */

    const image = await loadImage("./assets/texture.png");
    const texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
    draw();

/* ... */
}

如您所见,我在gl.texImage2D() 函数之后调用了draw() 函数。我不明白为什么会跳过这个 draw() 函数:

function main() {
    if (!init()) return;
    draw();
}

2022 年 11 月 6 日更新

function loadTexture(url) {
    return new Promise(resolve => {
        const image = new Image();
        image.onload = () => {
            const texture = gl.createTexture();
            gl.bindTexture(gl.TEXTURE_2D, texture);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
            resolve(texture);
        };
        image.src = url;
    });
}
async function init() {
    const texture = await loadTexture("./assets/texture.png");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    相关资源
    最近更新 更多