Ich versuche, zwei Maschen, ein Quadrat und ein Dreieck zu erstellen. Der Code ist am unteren Rand.WebGL VertexAttribPointer zeigt auf den falschen VBO
Zuerst erstelle ich ein Shader-Programm "program1", Array-Puffer "vertexBuffer1" und einen Element-Array-Puffer "indexBuffer1" für das erste Mesh. Das erste Netz ist ein Quadrat.
Dann mache ich das gleiche für die zweite Masche. Die zweite Masche ist ein Dreieck.
Wenn ich den Code ausführen bekomme ich den Fehler:
[.Offscreen-For-WebGL-000002B76A973870]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0
Ich habe nicht den Fehler, wenn ich diese Zeile aus kommentieren:
//gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0); // <- problem!
denke ich, was irgendwie passiert, dass Die vbo des Dreiecks ("vertexBuffer2") wird mit dem Shader-Programm des Quadrates ("program1") verbunden. Dies führt dazu, dass
gl.drawElements(gl.TRIANGLES, indices1.length, gl.UNSIGNED_SHORT, 0);
fehlschlägt, während es versucht, ein Quadrat aus dem Vertexpuffer Dreieck zu zeichnen.
verstehe ich nicht, warum
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0); // <- problem!
Ursachen "program1" auf "vertexBuffer2" zu verbinden, wenn das überhaupt das Problem ist. Wie mache ich diese zwei Programme ("program1" und "program2") verbinden Sie mit jedem ihrer Puffer?
<!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>