Reputation: 1152
I want to load textures without callbacks like .onload()
. I am trying to use texture from 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);
Expected result is:
But I have this:
I can see in the Network
tab that the image has been uploaded:
This line of code console.log(imageBitmap);
says that the image exists:
texImage2D()
documentation says that I can use ImageBitmap as source.
Updated
I tried to use the loadImage
function from this answer: 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);
/* ... */
}
But that didn't solve the problem.
Upvotes: 1
Views: 872
Reputation: 1152
This answer helped me to solve the problem: 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);
draw();
/* ... */
}
As you can see, I call the draw()
function after the gl.texImage2D()
function. I don't understand why this draw()
function is skipped:
function main() {
if (!init()) return;
draw();
}
Added 7/27/2023. I use this code to load textures and shaders using Fetch API (async/await): https://plnkr.co/edit/KaDgu8R6NJxnDEbO?preview
load-texture.js
import { gl } from "./webgl-context.js";
export default function loadTexture(url, minType = gl.NEAREST, magType = gl.NEAREST) {
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, minType);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magType);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
resolve(texture);
};
image.src = url;
});
}
index.js
async function init() {
const texture = await loadTexture("./assets/textures/texture.png",
gl.LINEAR, gl.LINEAR);
gl.bindTexture(gl.TEXTURE_2D, texture);
}
init();
Upvotes: 2
Reputation: 1
[enter image description here][1]Loading Imagebitmap in gl.texImage2D() method works only in webgl2. var gl = someCanvas.getContext("webgl2");
It is working for me. [1]: https://i.sstatic.net/vgGPz.png
Upvotes: -1