2つのメッシュ、正方形と三角形を作成しようとしています。コードは一番下にあります。WebGLのvertexAttribPointerが間違ったVBOを指しています
最初に、シェーダプログラム "program1"、配列バッファ "vertexBuffer1"、および要素配列バッファ "indexBuffer1"を最初のメッシュ用に作成します。最初のメッシュは正方形です。
次に、2番目のメッシュについても同じことをします。 2番目のメッシュは三角形です。私は、この行をコメントアウトする場合
[.Offscreen-For-WebGL-000002B76A973870]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0
私はエラーを取得していない:私は、コードを実行すると
私はエラーを取得する
//gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0); // <- problem!
私は何が起こっているかどうかしていることだと思います三角形のvbo(「vertexBuffer2」)が四角形のシェーダプログラム(「program1」)に接続されます。これにより、三角形頂点バッファから四角形を描画しようとすると、
gl.drawElements(gl.TRIANGLES, indices1.length, gl.UNSIGNED_SHORT, 0);
が失敗します。
私はしても問題がある場合、「vertexBuffer2」に接続するために、なぜ
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0); // <- problem!
原因「プログラム1」を理解していません。どのように2つのプログラム( "program1"と "program2")をそれぞれのバッファに接続させるのですか?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="canvas" width="500" height="450" style="border:1px solid black"></canvas>
<script>
// setup gl
var canvas = document.getElementById("canvas");
var gl = canvas.getContext("webgl");
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.clearColor(0.5, 0.5, 0.5, 0.9);
gl.clearDepth(1.0);
gl.viewport(0.0, 0.0, canvas.width, canvas.height);
// setup mesh 1
// // vertex shader
var vertexShader1 = gl.createShader(gl.VERTEX_SHADER);
var vertexShaderCode = `
// in
attribute vec3 position;
void main(void) {
gl_Position = vec4(position, 1.);
}
`;
gl.shaderSource(vertexShader1, vertexShaderCode);
gl.compileShader(vertexShader1);
// // fragment shader
var fragmentShader1 = gl.createShader(gl.FRAGMENT_SHADER);
var fragmentShaderCode = `
precision mediump float;
// in
void main(void) {
gl_FragColor = vec4(1., 0., 0., 1.);
}
`;
gl.shaderSource(fragmentShader1, fragmentShaderCode);
gl.compileShader(fragmentShader1);
// // program1
var program1 = gl.createProgram();
gl.attachShader(program1, vertexShader1);
gl.attachShader(program1, fragmentShader1);
gl.linkProgram(program1);
gl.useProgram(program1);
// // create buffer 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);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices1), gl.STATIC_DRAW);
var loc = gl.getAttribLocation(program1, "position");
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(loc);
var indices1 = [
0,1,2,
0,2,3,
];
var indexBuffer1 = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer1);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices1), gl.STATIC_DRAW);
// setup mesh 2
// // vertex shader
var vertexShader2 = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader2, vertexShaderCode); // uses same vertexShaderCode as above
gl.compileShader(vertexShader2);
// // fragment shader
var fragmentShader2 = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader2, fragmentShaderCode);
gl.compileShader(fragmentShader2);
// // program2
var program2 = gl.createProgram();
gl.attachShader(program2, vertexShader2);
gl.attachShader(program2, fragmentShader2);
gl.linkProgram(program2);
gl.useProgram(program2);
// // create buffer 2
var vertices2 = [ // triangle one less vertex than in buffer 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);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices2), gl.STATIC_DRAW);
var loc = gl.getAttribLocation(program2, "position");
// On the line below it seems like program1 instead of program2 gets connected to the vertexBuffer2
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0); // <- problem!
gl.enableVertexAttribArray(loc);
var indices2 = [
0,1,2,
];
var indexBuffer2 = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer2);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices2), gl.STATIC_DRAW);
// render
// // clear
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// // render mesh 1 (the square)
gl.useProgram(program1);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer1);
gl.drawElements(gl.TRIANGLES, indices1.length, gl.UNSIGNED_SHORT, 0); // <- this line fail
</script>
</body>
</html>