WebGL中缓冲区超出范围的常见原因是什么

WebGL中缓冲区超出范围的常见原因是什么,webgl,Webgl,我正在从事一个webgl项目。 当我调用gl.drawerElements时,会显示错误“范围超出缓冲区界限” 我确信我通过了正确的缓冲区长度或偏移量。但是,错误仍然在显现 我认为有几个原因可能导致错误。因此,我想问一下,如果您的项目中存在相同的问题,您检查了什么来解决此问题?在调用gl.drawerelements时,只有3个原因导致此错误 索引引用的顶点超出了缓冲区的范围 例如,创建一个缓冲区并在其中放置3个位置值 var buf = gl.createBuffer(); gl.bindBu

我正在从事一个webgl项目。 当我调用gl.drawerElements时,会显示错误“范围超出缓冲区界限”

我确信我通过了正确的缓冲区长度或偏移量。但是,错误仍然在显现


我认为有几个原因可能导致错误。因此,我想问一下,如果您的项目中存在相同的问题,您检查了什么来解决此问题?

在调用
gl.drawerelements时,只有3个原因导致此错误

  • 索引引用的顶点超出了缓冲区的范围

    例如,创建一个缓冲区并在其中放置3个位置值

    var buf = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buf);
    var data = [1,2,3,4,5,6,7,8,9]; // 3 (3 value) positions
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
    
    因为只有3个位置,所以唯一可能的索引是0、1和2。因此,如果在索引缓冲区中放入任何其他值,就会出现该错误

    var indexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf);
    var indices = [0,1,3]; // ERROR! That 3 is out of range
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
    
    // This will generate an out of bounds error because
    // the 3 index we put in the index buffer is out of range
    // as the only valid indices are 0, 1, and 2.
    gl.drawElements(gl.TRIANGLE, 3, gl.UNSIGNED_SHORT, 0);
    
  • 您试图绘制过多索引或设置偏移量超出范围

    鉴于上述设置,如果您这样做了

    gl.drawElements(gl.TRIANGLE, 4, gl.UNSIGNED_SHORT, 0); 
    
    你会超出范围,因为你只输入了3个指数,但你要求抽取4个。同样,如果更改偏移量

    gl.drawElements(gl.TRIANGLE, 3, gl.UNSIGNED_SHORT, 1);
    
    同样,你只放了3个索引,但你要求它画索引1,2,和3,而不是0,1,和2

  • 您将属性设置为访问过多数据

    让我们假设我们放置在三个3值位置,如上面所示。如果我们将属性设置为拉出三个4值位置,如下所示

    var size = 4; // ERROR! There are only 3 value per position
    gl.vertexAttribPointer(location, size, gl.FLOAT, false, 0, 0);
    
    该设置将尝试访问12个浮动数据(假设索引正确),但您只输入9个浮动数据。大小应等于3

    如果将步长或偏移(最后两个参数设置为
    gl.VertexAttribPointer
    )设置为错误的值,也可能会出现类似的问题。几乎所有WebGL程序都会在那里使用0,0。如果您正在做更奇特的事,请确保正确设置它们


  • 您可能没有将数组作为正确的类型传递。很容易忘记将顶点或索引从常规Javascript数组强制转换为

    例如(改编自gman的第一个示例):

    在Javascript中,它是一个IEEE64位浮点。例如,
    索引
    数组的第一个元素,
    3
    ,由以下64位表示:

    0000 0000 0001 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
    
    如果将常规Javascript数组传递到元素数组缓冲区中,那么当
    gl.drawerElements()
    要求将缓冲区解释为无符号短(16位整数)时,它会将前64位视为4组16位,并读取以下值:

    0000 0000 0001 1000  =  24
    0000 0000 0000 0000  =   0
    0000 0000 0000 0000  =   0
    0000 0000 0000 0000  =   0
    

    当然,24超出了4元素顶点位置数组缓冲区的范围。

    出现此错误,因为我使用了:

    gl.drawerelements(绘图模式,计数,this.gl.UNSIGNED\u INT,0)

    而不是:

    gl.drawerelements(drawingMode,count,this.gl.UNSIGNED\u SHORT,0)


    (加载的数据是UINT16数组,当然不是UINT32数组)。

    Amen!这个保存的方法帮助我找到了代码中的错误。在我的例子中,我有gl.bindBuffer(gl.ELEMENT\u ARRAY\u BUFFER,…)后跟gl.bufferData(gl.ARRAY\u BUFFER,…)(注意数组\u BUFFER/元素\u ARRAY\u BUFFER不匹配).我犯了同样的一般错误。@Jadrian Miles#2阿门也救了我一命
    0000 0000 0001 1000  =  24
    0000 0000 0000 0000  =   0
    0000 0000 0000 0000  =   0
    0000 0000 0000 0000  =   0