【问题标题】:Using array of images as texture in WebGL在 WebGL 中使用图像数组作为纹理
【发布时间】:2013-09-06 18:43:23
【问题描述】:

如何在 WebGL 中使用纹理数组(包含不同的图像)而不分别初始化每个纹理?我想显示一个立方体和一个金字塔(组织为一个数组),每个都有不同的纹理图像。这是代码的一部分(用于初始化纹理):

function handleTexture(texture) {
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.Img);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
    gl.generateMipmap(gl.TEXTURE_2D);
    gl.bindTexture(gl.TEXTURE_2D, null);
}

function initTextures() {
    for (i=0; i<2; i++) {
        tex[i] = gl.createTexture();
        tex[i].Img = new Image();
        tex[i].Img.onload = function() { handleTexture(tex[i]); }
        tex[i].Img.src = texImgs[i];   // The name of the image file
    }
}

立方体和金字塔显示为黑色(无纹理),我在页面中收到此错误:

Uncaught TypeError: Cannot read property 'Img' of undefined  // gl.texImage2D()
tex.(anonymous function).Img.onload                          // tex[i].Img.onload = ...

如果我单独初始化纹理,不使用数组,而是使用tex1和tex2,我没有这个错误。有关如何使用数组执行此操作的任何建议?

【问题讨论】:

  • 您可以查看this 在 WebGL 中向画布添加纹理

标签: javascript webgl


【解决方案1】:

当你这样做时:

tex[i] = gl.createTexture();

tex[i] 成为WebGLTexture 的一种类型,您不能像使用.Img 属性那样在该对象上附加新属性。所以稍微更正确的版本是:

var tex = [], texImgs = ['pyra.jpg', 'cube.jpg'];

function handleTexture(myTexture) {
    myTexture.texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, myTexture.texture);

    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, myTexture.image);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
    gl.generateMipmap(gl.TEXTURE_2D);
    gl.bindTexture(gl.TEXTURE_2D, null);
}

function initTextures() {
    for (var i=0; i<2; i++) {
        (function(index) {
            tex[index] = new Object();
            tex[index].texture = null;
            tex[index].image = new Image();
            tex[index].image.onload = function() { handleTexture(tex[index]); }
            tex[index].image.src = texImgs[index];   // The name of the image file
        })(i);
    }
}

请注意,您创建的对象将 imagetexture 属性分开。

希望对你有所帮助。

编辑:

闭包弄乱了tex的索引。

【讨论】:

  • 试过这个,但现在立方体和金字塔不显示了。然后有这个错误:Uncaught TypeError: Cannot set property 'Img' of undefined (in tex[i].Img = new Image())。无论如何,如果我不使用数组初始化纹理,而是使用 tex1 = gl.createTexture(),之后我仍然可以设置 tex1.Img = new Image()。
  • 已编辑答案,尝试将tex[i] 创建为新对象,也许这就是问题所在。
  • 现在显示立方体和金字塔,但仍为黑色。然后就是这个错误:Uncaught TypeError: Cannot set property 'texture' of undefined (myTexture.texture = gl.createTexture()).
  • 已编辑。我完全忘记了 for 循环中不存在的闭包和 tex[i] 的异步调用。它实际上是试图在tex[3] 上调用handleTexture。这现在应该 100% 工作。 :]
  • 谢谢!它现在正在工作。反正WebGL好像真的很讨厌数组。
猜你喜欢
  • 2019-07-31
  • 1970-01-01
  • 2020-04-03
  • 2021-05-23
  • 1970-01-01
  • 2014-08-07
  • 2014-04-29
  • 1970-01-01
  • 2012-11-17
相关资源
最近更新 更多