program, array_buffer, element_array_buffer 를 구조화하여 한 값에 이들에 해당하는 값들을 저장하여 각각을 바인딩/언바인딩 하지 않고 해당 값을 바인딩/언바인딩하여 렌더링을 한다.
언바인딩을 하지 않은 상태로 이후 작업에서 일부 버퍼에 대한 바인딩을 놓친다면 이전에 바인딩한 값에 영향을 받아 렌더링이 진행된다. 예를 들어 사각형을 렌더링한 후 array_buffer 부분에 대한 언바인딩/바인딩 작업을 실수로 빼먹은 경우 삼각형은 사각형을 렌더링할 때 사용한 정점 정보를 사용하게 된다.

# Rectangle FragmentShader
var fragmentShaderSource = `#version 300 es
precision mediump float;
layout(location=0) out vec4 outColor;
uniform vec4 u_color;
void main() {
outColor = u_color;
}
`;
# Triangle FragmentShader
var triangleFragmentShaderSource = `#version 300 es
precision mediump float;
layout(location=0) out vec4 outColor;
uniform vec4 u_tcolor;
void main() {
outColor = u_tcolor;
}
`;
...
# Draw call
function drawScene() {
// -- Rectangle Uniform setting
// -- Rectangle Buffer 데이터 설명
gl.useProgram(program);
gl.bindVertexArray(rectangleVAO);
var location = gl.getUniformLocation(program, 'u_color');
gl.uniform4f(location, 0.0, 1.0, 0.0, 1.0); // 사각형은 항상 초록색
var offsetLocation = gl.getUniformLocation(program, 'u_offset');
gl.uniform4f(offsetLocation, x_offset, 0.0, 0.0, 0.0);
// -- Draw call
// gl.drawArrays(gl.TRIANGLES, 0, 3);
gl.drawElements(gl.TRIANGLES,
6,
gl.UNSIGNED_SHORT,
0);
gl.useProgram(null);
gl.bindVertexArray(null);
gl.useProgram(triangleProgram);
gl.bindVertexArray(triangleVAO);
var location = gl.getUniformLocation(triangleProgram, 'u_tcolor');
gl.uniform4f(location, x_offset, 0.3, 0.8, 1.0); // 슬라이더가 R값에 영향을 줌
// -- Triangle Draw call
gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0);
gl.useProgram(null);
gl.bindVertexArray(null);
}

function drawScene() {
...
// -- Additional Rectangle Draw call
gl.useProgram(program);
gl.bindVertexArray(rectangleVAO);
var additionalOffsetLocation = gl.getUniformLocation(program, 'u_offset');
gl.uniform4f(additionalOffsetLocation, -x_offset, 0.2, 0.0, 0.0);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
gl.useProgram(null);
gl.bindVertexArray(null);
}
