사각형과 삼각형 두 개의 메시를 만들려고합니다. 코드가 맨 아래에 있습니다.WebGL vertexAttribPointer가 잘못된 VBO를 가리 킵니다
먼저 셰이더 프로그램 "program1", 배열 버퍼 "vertexBuffer1"및 첫 번째 메쉬에 대한 요소 배열 버퍼 "indexBuffer1"을 만듭니다. 첫 번째 메쉬는 사각형입니다.
두 번째 메쉬에 대해서도 동일한 작업을 수행합니다. 두 번째 메쉬는 삼각형입니다. 나는이 줄을 주석 경우
[.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);
은 삼각형 버텍스 버퍼에서 사각형을 그리는 데 실패합니다.
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 0, 0); // <- problem!
원인 "프로그램 1은"을 "vertexBuffer2"를 연결하는 이유도 문제가있는 경우
나는 이해가 안 돼요. 두 개의 프로그램 ("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>