WebGL VertexAttribute指针指向错误的VBO

WebGL VertexAttribute指针指向错误的VBO,webgl,shader,Webgl,Shader,我正在尝试创建两个网格,一个正方形和一个三角形。代码在底部 我首先为第一个网格创建着色器程序“program1”、数组缓冲区“vertexBuffer1”和元素数组缓冲区“indexBuffer1”。第一个网格是正方形 然后对第二个网格执行相同的操作。第二个网格是三角形 当我运行代码时,我得到一个错误: [.Offscreen-For-WebGL-00000 2B76A973870]GL错误:GL_无效_操作:GLDraweElements:尝试访问属性0中超出范围的顶点 如果我注释掉这一行,我

我正在尝试创建两个网格,一个正方形和一个三角形。代码在底部

我首先为第一个网格创建着色器程序“program1”、数组缓冲区“vertexBuffer1”和元素数组缓冲区“indexBuffer1”。第一个网格是正方形

然后对第二个网格执行相同的操作。第二个网格是三角形

当我运行代码时,我得到一个错误:

[.Offscreen-For-WebGL-00000 2B76A973870]GL错误:GL_无效_操作:GLDraweElements:尝试访问属性0中超出范围的顶点

如果我注释掉这一行,我不会得到错误:

//gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0); // <- problem!
尝试从三角形顶点缓冲区绘制正方形时失败

我不明白为什么

gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0); // <- problem!
gl.vertexattributepointer(loc,3,gl.FLOAT,false,0,0);// 注意,指定常规顶点属性数组的状态

首先创建并绑定
vertexBuffer1
indexBuffer1
program1
。并指定:

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
....
var loc = gl.getAttribLocation(program1, "position"); // loc == 0
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(loc);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer2);
....
var loc = gl.getAttribLocation(program2, "position"); // loc == 0
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(loc);
其次,创建并绑定
vertexBuffer2
indexBuffer2
program2
。并指定:

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
....
var loc = gl.getAttribLocation(program1, "position"); // loc == 0
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(loc);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer2);
....
var loc = gl.getAttribLocation(program2, "position"); // loc == 0
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(loc);
最后你打电话:

gl.useProgram(program1);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer1);
gl.drawElements(gl.TRIANGLES, indices1.length, gl.UNSIGNED_SHORT, 0);
此时,顶点缓冲区状态仍指
vertexBuffer2
,因为这是您为索引为0的通用顶点属性指定的最后一个状态

更改代码如下:

gl.linkProgram(program1);
var loc1 = gl.getAttribLocation(program1, "position");

....

gl.useProgram(program1);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(loc);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer1);
gl.drawElements(gl.TRIANGLES, indices1.length, gl.UNSIGNED_SHORT, 0);
请注意,在绘制网格之前立即设置顶点属性“状态”就足够了。用于管理可使用的顶点属性的不同状态,这些属性在WebGL 2.0中受支持,或可通过WebGL 1.0获得


请参阅代码片段:

//安装程序
var canvas=document.getElementById(“canvas”);
var gl=canvas.getContext(“webgl”);
总帐启用(总帐深度测试);
德普丰克总帐(莱夸尔总帐);
gl.clearColor(0.5,0.5,0.5,0.9);
gl.净空深度(1.0);
总图视口(0.0,0.0,canvas.width,canvas.height);
//设置网格1
////顶点着色器
var vertexShader1=gl.createShader(gl.VERTEX\u着色器);
变量vertexShaderCode=`
//在
属性向量3位置;
真空总管(真空){
gl_位置=vec4(位置,1.);
}
`;
gl.shaderSource(vertexShader1,vertexShaderCode);
gl.compileShader(vertexShader1);
////片段着色器
var fragmentShader1=gl.createShader(gl.FRAGMENT\u着色器);
var fragmentShaderCode=`
精密中泵浮子;
//在
真空总管(真空){
gl_FragColor=vec4(1,0,0,1.);
}
`;
gl.shaderSource(fragmentShader1,fragmentShaderCode);
总帐编译管理员(fragmentShader1);
////程序1
var program1=gl.createProgram();
gl.attachShader(程序1,顶点着色器1);
gl.attachShader(程序1,碎片着色器1);
总账链接程序(程序1);
变量loc1=gl.GetAttriblLocation(程序1,“位置”);
////创建缓冲区1
var vertices1=[//suqare
-0.5, -0.5, 0,
0.5, -0.5, 0,
0.5, 0.5, 0,
-0.5, 0.5, 0,
];
var vertexBuffer1=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer1);
总账缓冲数据(总账数组缓冲区、新Float32Array(vertices1)、总账静态绘图);
变量指标1=[
0,1,2,
0,2,3,
];
var indexBuffer1=gl.createBuffer();
gl.bindBuffer(gl.ELEMENT\u ARRAY\u BUFFER,indexBuffer1);
总账缓冲数据(总账元素数组缓冲区、新UINT16数组(指示1)、总账静态绘图);
//设置网格2
////顶点着色器
var vertexShader2=gl.createShader(gl.VERTEX\u着色器);
gl.shaderSource(vertexShader2,vertexShaderCode);//使用与上述相同的vertexShaderCode
gl.compileShader(vertexShader2);
////片段着色器
var fragmentShader2=gl.createShader(gl.FRAGMENT\u着色器);
gl.shaderSource(fragmentShader2,fragmentShaderCode);
总帐编译管理员(fragmentShader2);
////程序2
var program2=gl.createProgram();
gl.attachShader(程序2,顶点着色器2);
gl.attachShader(程序2,碎片着色器2);
总账链接程序(程序2);
变量loc2=gl.GetAttriblLocation(程序2,“位置”);
////创建缓冲区2
var vertices2=[//三角形比缓冲区1中的顶点少一个
-0.5, -0.5, 0,
0.5, -0.5, 0,
0.5, 0.5, 0,
];
var vertexBuffer2=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer2);
总账缓冲数据(总账数组缓冲区、新Float32Array(vertices2)、总账静态绘图);
变量指标2=[
0,1,2,
];
var indexBuffer2=gl.createBuffer();
gl.bindBuffer(gl.ELEMENT\u ARRAY\u BUFFER,indexBuffer2);
总账缓冲数据(总账元素数组缓冲区、新UINT16数组(标记2)、总账静态绘图);
//渲染
////清除
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
////渲染网格1(正方形)
总账使用计划(计划1);
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer1);
gl.VertexAttributePointer(loc1,3,gl.FLOAT,false,0,0)//