Ответ 1
Самый простой способ исправить это - сделать текстуру 1x1 во время создания.
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
new Uint8Array([255, 0, 0, 255])); // red
Затем при загрузке изображения вы можете заменить текстуру 1x1 пикселя на изображение. Флаги не нужны, и ваша сцена будет отображать цвет по вашему выбору до загрузки изображения.
var img = new Image();
img.src = "http://someplace/someimage.jpg";
img.onload = function() {
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
// then either generate mips if the image uses power-of-2 dimensions or
// set the filtering correctly for non-power-of-2 images.
setupTextureFilteringAndMips(img.width, img.height);
}
Как раз для того, чтобы спасти людей от беды в следующей проблеме, с которыми они, скорее всего, столкнутся, WebGL требует mips или требуется фильтрация, которая не требует mips. Кроме того, для использования mips требуются текстуры с размерами, которые имеют мощность 2 (то есть 1, 2, 4, 8,..., 256, 512 и т.д.). Таким образом, при загрузке изображения вы, скорее всего, захотите настроить фильтрацию для правильной обработки.
function isPowerOf2(value) {
return (value & (value - 1)) == 0;
};
function setupTextureFilteringAndMips(width, height) {
if (isPowerOf2(width) && isPowerOf2(height) {
// the dimensions are power of 2 so generate mips and turn on
// tri-linear filtering.
gl.generateMipmap(gl.TEXTURE_2D);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
} else {
// at least one of the dimensions is not a power of 2 so set the filtering
// so WebGL will render it.
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);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
}
}