WebGL尝试访问属性2错误

时间:2018-04-27 02:28:29

标签: webgl render

我知道这个问题已经被提了很多,但没有一个解决方案真的适合我的情况。我想在画布上添加第二种类型的对象,代码如下所示。我知道我提供的东西不多,但它起步很快。如果您认为自己有预感,请多询问一下。下面的代码在我的渲染函数中。

到目前为止,我已经检查了

  1. 我的点数组中有足够的顶点
  2. 我的法线数组中有足够的法向量
  3. 我的texCoords数组中有足够的纹理坐标
  4. 创建地形时添加的矢量与我的螺旋桨之间没有不匹配。
  5. 地形渲染得很好,纹理,灯光和所有但是,我无法让螺旋桨渲染。我得到了上面列出的错误。我之前已经在画布中添加了多个对象,并且从未遇到过像这样的错误。

    //----------------------------------------- Draw Terrain ------------------------------------
      var i = 0;
      for(var row=0-dimension; row<dimension; row+=3){
        for(var col=0-dimension; col<dimension; col+=3, i++){
          var mv = mult(viewer, mult(translate(row, -1, col), mult(scale[i],rot[i])));
          gl.uniformMatrix4fv(modelViewLoc, false, flatten(mv));
          gl.uniformMatrix3fv(normalLoc, false, flatten(normalMatrix(mv, true)));
          gl.drawArrays( gl.TRIANGLES, 0, index);
        }
      }
    
      //----------------------------------------- Draw Propeller ------------------------------------
      mv = mult(viewer, mult( translate(-2.1, -2.9, -.2), scalem(4,5,5)));
      gl.uniformMatrix4fv(modelViewLoc, false, flatten(mv));
      gl.uniformMatrix3fv(normalLoc, false, flatten(normalMatrix(mv, true)));
      gl.drawArrays( gl.TRIANGLES, propellerStart, points.length);
    

    有什么方法可以使用&#34;属性2&#34;在错误消息中跟踪变量给我这个问题?

    感谢帮助!

1 个答案:

答案 0 :(得分:2)

你不明白哪一部分?错误很明显,无论您附加到属性2的缓冲区是否都不足以处理propellerStart, points.length绘制请求。

首先要确定哪个属性是属性2.通过打印属性位置来执行此操作。你的分数,法线还是texcoords?

您应该已经使用gl.getAttribLocation在某处查找它们,因此请打印出这些值,找出哪一个是#2。

然后查看附加到该属性的缓冲区的大小。要做到这一点,你会打电话给。

gl.bindBuffer(gl.ARRAY_BUFFER, someBuffer);
gl.vertexAttribPointer(locationForAttribute2, size, type, normalize, stride, offset);

所以我们从上面的代码中了解了someBuffer。我们还需要了解sizetypestrideoffset

在其他地方,您使用

填充了数据缓冲区
gl.bindBuffer(gl.ARRAEY_BUFFER, someBuffer);
gl.bufferData(gl.ARRAY_BUFFER, someData, ...);

所以你需要找到someData的大小。

sizeOfBuffer = someData.length * someData.BYTES_PER_ELEMENT

让它成为1000个元素Float32Array,因此someData.length为1000而someData.BYTES_PER_ELEMENT为4,因此sizeOfBuffer为4000。

使用所有这些,您现在可以检查缓冲区是否太小。 (注意:我们已经知道它太小了,因为浏览器告诉了我们,但如果你想知道如何自己计算它)

我们说size为3,typegl.FLOATstride为32,offset为12(注意:我个人从不使用除stride = 0和offset = 0之外的任何东西

让我们说points.length = 50

numPoints = points.length;
bytesPerElement = size * 4;   // because a gl.FLOAT is 4 bytes
realStride = stride === 0 ? bytesPerElement : stride;
bytesNeeded = realStride * (numPoints - 1) + bytesPerElement;
在这种情况下,

bytesNeeded是(64 * 49)+ 12 = 3148

现在我们知道需要多少字节。缓冲区有足够的数据吗?当你调用绘图时,我们传入了偏移量propellerStart。我们假设它是900,并且属性中有offset

bufferSizeNeeded = offset + propellerStart + bytesNeeded

所以bufferSizeNeeded = 12 + 900 + 3148是4060.由于4060是> sizeOfBuffer这是4000,你会得到你得到的错误。

无论如何,关键在于你要弄清楚属性#2使用哪个缓冲区,然后去看看为什么你的缓冲区太小了。你对drawArrays的偏移是错误的吗?你的步伐太大了吗?您的偏移在vertexAttribPointer中是错误的(它的字节数不是单位数)。你把错误的尺寸(1,2,3,4)。你错误地计算了点数吗?