diff options
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-vertex-array-object.html')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-vertex-array-object.html | 738 |
1 files changed, 738 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-vertex-array-object.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-vertex-array-object.html new file mode 100644 index 000000000..4bd2a4fd8 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-vertex-array-object.html @@ -0,0 +1,738 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL OES_vertex_array_object Conformance Tests</title> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +<!-- comment in the script tag below to test through JS emulation of the extension. --> +<!-- +<script src="../../../demos/google/resources/OESVertexArrayObject.js"></script> +--> +</head> +<body> +<div id="description"></div> +<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> +<div id="console"></div> +<script id="vshader" type="x-shader/x-vertex"> +attribute vec4 a_position; +attribute vec4 a_color; +varying vec4 v_color; +void main(void) { + gl_Position = a_position; + v_color = a_color; +} +</script> +<script id="fshader" type="x-shader/x-fragment"> +precision mediump float; +varying vec4 v_color; +void main(void) { + gl_FragColor = v_color; +} +</script> +<script> +"use strict"; +description("This test verifies the functionality of the OES_vertex_array_object extension, if it is available."); + +debug(""); + +var wtu = WebGLTestUtils; +var canvas = document.getElementById("canvas"); +var gl = wtu.create3DContext(canvas); +var ext = null; +var vao = null; + +if (!gl) { + testFailed("WebGL context does not exist"); +} else { + testPassed("WebGL context exists"); + + // Setup emulated OESVertexArrayObject if it has been included. + if (window.setupVertexArrayObject) { + debug("using emulated OES_vertex_array_object"); + setupVertexArrayObject(gl); + } + + // Run tests with extension disabled + runBindingTestDisabled(); + + // Query the extension and store globally so shouldBe can access it + ext = gl.getExtension("OES_vertex_array_object"); + if (!ext) { + testPassed("No OES_vertex_array_object support -- this is legal"); + + runSupportedTest(false); + } else { + testPassed("Successfully enabled OES_vertex_array_object extension"); + + runSupportedTest(true); + runBindingTestEnabled(); + runObjectTest(); + runAttributeTests(); + runAttributeValueTests(); + runDrawTests(); + runUnboundDeleteTests(); + runBoundDeleteTests(); + runArrayBufferBindTests(); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors"); + } +} + +function runSupportedTest(extensionEnabled) { + var supported = gl.getSupportedExtensions(); + if (supported.indexOf("OES_vertex_array_object") >= 0) { + if (extensionEnabled) { + testPassed("OES_vertex_array_object listed as supported and getExtension succeeded"); + } else { + testFailed("OES_vertex_array_object listed as supported but getExtension failed"); + } + } else { + if (extensionEnabled) { + testFailed("OES_vertex_array_object not listed as supported but getExtension succeeded"); + } else { + testPassed("OES_vertex_array_object not listed as supported and getExtension failed -- this is legal"); + } + } +} + +function runBindingTestDisabled() { + debug(""); + debug("Testing binding enum with extension disabled"); + + // Use the constant directly as we don't have the extension + var VERTEX_ARRAY_BINDING_OES = 0x85B5; + + gl.getParameter(VERTEX_ARRAY_BINDING_OES); + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "VERTEX_ARRAY_BINDING_OES should not be queryable if extension is disabled"); +} + +function runBindingTestEnabled() { + debug(""); + debug("Testing binding enum with extension enabled"); + + shouldBe("ext.VERTEX_ARRAY_BINDING_OES", "0x85B5"); + + gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "VERTEX_ARRAY_BINDING_OES query should succeed if extension is enabled"); + + // Default value is null + if (gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) === null) { + testPassed("Default value of VERTEX_ARRAY_BINDING_OES is null"); + } else { + testFailed("Default value of VERTEX_ARRAY_BINDING_OES is not null"); + } + + debug(""); + debug("Testing binding a VAO"); + var vao0 = ext.createVertexArrayOES(); + var vao1 = ext.createVertexArrayOES(); + shouldBeNull("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES)"); + ext.bindVertexArrayOES(vao0); + if (gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) == vao0) { + testPassed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is expected VAO"); + } else { + testFailed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is not expected VAO") + } + ext.bindVertexArrayOES(vao1); + if (gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) == vao1) { + testPassed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is expected VAO"); + } else { + testFailed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is not expected VAO") + } + ext.deleteVertexArrayOES(vao1); + shouldBeNull("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES)"); + ext.bindVertexArrayOES(vao1); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "binding a deleted vertex array object"); + ext.bindVertexArrayOES(null); + shouldBeNull("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES)"); + ext.deleteVertexArrayOES(vao1); +} + +function runObjectTest() { + debug(""); + debug("Testing object creation"); + + vao = ext.createVertexArrayOES(); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "createVertexArrayOES should not set an error"); + shouldBeNonNull("vao"); + + // Expect false if never bound + shouldBeFalse("ext.isVertexArrayOES(vao)"); + ext.bindVertexArrayOES(vao); + shouldBeTrue("ext.isVertexArrayOES(vao)"); + ext.bindVertexArrayOES(null); + shouldBeTrue("ext.isVertexArrayOES(vao)"); + + shouldBeFalse("ext.isVertexArrayOES(null)"); + + ext.deleteVertexArrayOES(vao); + vao = null; +} + +function runAttributeTests() { + debug(""); + debug("Testing attributes work across bindings"); + + var states = []; + + var attrCount = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); + for (var n = 0; n < attrCount; n++) { + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + + var state = {}; + states.push(state); + + var vao = state.vao = ext.createVertexArrayOES(); + ext.bindVertexArrayOES(vao); + + var enableArray = (n % 2 == 0); + if (enableArray) { + gl.enableVertexAttribArray(n); + } else { + gl.disableVertexAttribArray(n); + } + + if (enableArray) { + var buffer = state.buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.STATIC_DRAW); + + gl.vertexAttribPointer(n, 1 + n % 4, gl.FLOAT, true, n * 4, n * 4); + } + + if (enableArray) { + var elbuffer = state.elbuffer = gl.createBuffer(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elbuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 1024, gl.STATIC_DRAW); + } + + ext.bindVertexArrayOES(null); + } + + var anyMismatch = false; + for (var n = 0; n < attrCount; n++) { + var state = states[n]; + + ext.bindVertexArrayOES(state.vao); + + var shouldBeEnabled = (n % 2 == 0); + var isEnabled = gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_ENABLED); + if (shouldBeEnabled != isEnabled) { + testFailed("VERTEX_ATTRIB_ARRAY_ENABLED not preserved"); + anyMismatch = true; + } + + var buffer = gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); + if (shouldBeEnabled) { + if (buffer == state.buffer) { + // Matched + if ((gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_SIZE) == 1 + n % 4) && + (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_TYPE) == gl.FLOAT) && + (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED) == true) && + (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_STRIDE) == n * 4) && + (gl.getVertexAttribOffset(n, gl.VERTEX_ATTRIB_ARRAY_POINTER) == n * 4)) { + // Matched + } else { + testFailed("VERTEX_ATTRIB_ARRAY_* not preserved"); + anyMismatch = true; + } + } else { + testFailed("VERTEX_ATTRIB_ARRAY_BUFFER_BINDING not preserved"); + anyMismatch = true; + } + } else { + // GL_CURRENT_VERTEX_ATTRIB is not preserved + if (buffer) { + testFailed("VERTEX_ATTRIB_ARRAY_BUFFER_BINDING not preserved"); + anyMismatch = true; + } + } + + var elbuffer = gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING); + if (shouldBeEnabled) { + if (elbuffer == state.elbuffer) { + // Matched + } else { + testFailed("ELEMENT_ARRAY_BUFFER_BINDING not preserved"); + anyMismatch = true; + } + } else { + if (elbuffer == null) { + // Matched + } else { + testFailed("ELEMENT_ARRAY_BUFFER_BINDING not preserved"); + anyMismatch = true; + } + } + } + ext.bindVertexArrayOES(null); + if (!anyMismatch) { + testPassed("All attributes preserved across bindings"); + } + + for (var n = 0; n < attrCount; n++) { + var state = states[n]; + ext.deleteVertexArrayOES(state.vao); + } +} + +function runAttributeValueTests() { + debug(""); + debug("Testing that attribute values are not attached to bindings"); + + var v; + var vao0 = ext.createVertexArrayOES(); + var anyFailed = false; + + ext.bindVertexArrayOES(null); + gl.vertexAttrib4f(0, 0, 1, 2, 3); + + v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB); + if (!(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)) { + testFailed("Vertex attrib value not round-tripped?"); + anyFailed = true; + } + + ext.bindVertexArrayOES(vao0); + + v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB); + if (!(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)) { + testFailed("Vertex attrib value reset across bindings"); + anyFailed = true; + } + + gl.vertexAttrib4f(0, 4, 5, 6, 7); + ext.bindVertexArrayOES(null); + + v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB); + if (!(v[0] == 4 && v[1] == 5 && v[2] == 6 && v[3] == 7)) { + testFailed("Vertex attrib value bound to buffer"); + anyFailed = true; + } + + if (!anyFailed) { + testPassed("Vertex attribute values are not attached to bindings") + } + + ext.bindVertexArrayOES(null); + ext.deleteVertexArrayOES(vao0); +} + +function runDrawTests() { + debug(""); + debug("Testing draws with various VAO bindings"); + + canvas.width = 50; canvas.height = 50; + gl.viewport(0, 0, canvas.width, canvas.height); + + var vao0 = ext.createVertexArrayOES(); + var vao1 = ext.createVertexArrayOES(); + var vao2 = ext.createVertexArrayOES(); + + var positionLocation = 0; + var colorLocation = 1; + + var program = wtu.setupSimpleVertexColorProgram(gl, positionLocation, colorLocation); + + function setupQuad(s, colorsInArray) { + var vertexObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ + 1.0 * s, 1.0 * s, 0.0, + -1.0 * s, 1.0 * s, 0.0, + -1.0 * s, -1.0 * s, 0.0, + 1.0 * s, 1.0 * s, 0.0, + -1.0 * s, -1.0 * s, 0.0, + 1.0 * s, -1.0 * s, 0.0]), gl.STATIC_DRAW); + gl.enableVertexAttribArray(positionLocation); + gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0); + + // Test switching between VAOs that have different number of enabled arrays + if (colorsInArray) { + var vertexObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ + 0.0, 0.0, 0.0, 1.0, + 0.0, 0.0, 0.0, 1.0, + 0.0, 0.0, 0.0, 1.0, + 0.0, 0.0, 0.0, 1.0, + 0.0, 0.0, 0.0, 1.0, + 0.0, 0.0, 0.0, 1.0]), gl.STATIC_DRAW); + gl.enableVertexAttribArray(colorLocation); + gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0); + } else { + gl.disableVertexAttribArray(colorLocation); + } + }; + + function verifyDiagonalPixels(s, expectedInside, drawDescription) { + // Tests pixels along a diagonal running from the center of the canvas to the (0, 0) corner. + // Values on the points list indicate relative position along this diagonal. + var points = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0]; + for (var n = 0; n < points.length; n++) { + var expected = points[n] <= s ? expectedInside : 255; + var x = Math.round((1 - points[n]) * canvas.width / 2); + var y = Math.round((1 - points[n]) * canvas.height / 2); + wtu.checkCanvasRect(gl, x, y, 1, 1, [expected, expected, expected, 255], + "Drawing " + drawDescription + " should pass", 2); + } + }; + function verifyDraw(drawDescription, s, colorsInArray) { + wtu.clearAndDrawUnitQuad(gl); + var expectedInside = colorsInArray ? 0 : 128; + verifyDiagonalPixels(s, expectedInside, drawDescription); + }; + + // Setup all bindings + setupQuad(1, true); + ext.bindVertexArrayOES(vao0); + setupQuad(0.5, true); + ext.bindVertexArrayOES(vao1); + setupQuad(0.25, true); + ext.bindVertexArrayOES(vao2); + setupQuad(0.75, false); + + gl.vertexAttrib4f(colorLocation, 0.5, 0.5, 0.5, 1); + + // Verify drawing + ext.bindVertexArrayOES(null); + verifyDraw("with the default VAO", 1, true); + ext.bindVertexArrayOES(vao0); + verifyDraw("with VAO #0", 0.5, true); + ext.bindVertexArrayOES(vao1); + verifyDraw("with VAO #1", 0.25, true); + ext.bindVertexArrayOES(vao2); + verifyDraw("with VAO that has the color array disabled", 0.75, false); + + // Verify bound VAO after delete + ext.bindVertexArrayOES(vao1); + ext.deleteVertexArrayOES(vao0); + verifyDraw("after deleting another VAO", 0.25, true); + ext.deleteVertexArrayOES(vao1); + verifyDraw("after deleting the VAO that was bound", 1, true); + + // Disable global vertex attrib array + gl.disableVertexAttribArray(positionLocation); + gl.disableVertexAttribArray(colorLocation); + + // Check that constant values are treated correctly as not being part of VAO state. + var positionLoc = 0; + var colorLoc = 1; + var gridRes = 1; + wtu.setupIndexedQuad(gl, gridRes, positionLoc); + // Set the vertex color to red. + gl.vertexAttrib4f(colorLoc, 1, 0, 0, 1); + + var vao0 = ext.createVertexArrayOES(); + ext.bindVertexArrayOES(vao0); + var program = wtu.setupSimpleVertexColorProgram(gl, positionLoc, colorLoc); + wtu.setupIndexedQuad(gl, gridRes, positionLoc); + // Set the vertex color to green. + gl.vertexAttrib4f(colorLoc, 0, 1, 0, 1); + wtu.clearAndDrawIndexedQuad(gl, gridRes); + wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green"); + ext.deleteVertexArrayOES(vao0); + wtu.clearAndDrawIndexedQuad(gl, gridRes); + wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green"); +} + +function runUnboundDeleteTests() { + debug(""); + debug("Testing using buffers that are deleted when attached to unbound VAOs"); + + var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_position", "a_color"]); + gl.useProgram(program); + + var positionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + gl.bufferData( + gl.ARRAY_BUFFER, + new Float32Array([ + 1.0, 1.0, + -1.0, 1.0, + -1.0, -1.0, + 1.0, -1.0]), + gl.STATIC_DRAW); + + var colors = [ + [255, 0, 0, 255], + [ 0, 255, 0, 255], + [ 0, 0, 255, 255], + [ 0, 255, 255, 255] + ]; + var colorBuffers = []; + var elementBuffers = []; + var vaos = []; + for (var ii = 0; ii < colors.length; ++ii) { + var vao = ext.createVertexArrayOES(); + vaos.push(vao); + ext.bindVertexArrayOES(vao); + // Set the position buffer + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + gl.enableVertexAttribArray(0); + gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); + + var elementBuffer = gl.createBuffer(); + elementBuffers.push(elementBuffer); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer); + gl.bufferData( + gl.ELEMENT_ARRAY_BUFFER, + new Uint8Array([0, 1, 2, 0, 2, 3]), + gl.STATIC_DRAW); + + // Setup the color attrib + var color = colors[ii]; + if (ii < 3) { + var colorBuffer = gl.createBuffer(); + colorBuffers.push(colorBuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array( + [ color[0], color[1], color[2], color[3], + color[0], color[1], color[2], color[3], + color[0], color[1], color[2], color[3], + color[0], color[1], color[2], color[3] + ]), gl.STATIC_DRAW); + gl.enableVertexAttribArray(1); + gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 0, 0); + } else { + gl.vertexAttrib4f(1, color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255); + } + } + + // delete the color buffers AND the position buffer. + ext.bindVertexArrayOES(null); + for (var ii = 0; ii < colorBuffers.length; ++ii) { + gl.deleteBuffer(colorBuffers[ii]); + gl.deleteBuffer(elementBuffers[ii]); + ext.bindVertexArrayOES(vaos[ii]); + var boundBuffer = gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); + // The buffers should still be valid at this point, since it was attached to the VAO + if(boundBuffer != colorBuffers[ii]) { + testFailed("buffer removed even though it is still attached to a VAO"); + } + } + + ext.bindVertexArrayOES(null); + gl.deleteBuffer(positionBuffer); + + // Render with the deleted buffers. As they are referenced by VAOs they + // must still be around. + for (var ii = 0; ii < colors.length; ++ii) { + var color = colors[ii]; + ext.bindVertexArrayOES(vaos[ii]); + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0); + wtu.checkCanvas(gl, color, "should be " + color); + } + + // Clean up. + for (var ii = 0; ii < colorBuffers.length; ++ii) { + ext.deleteVertexArrayOES(vaos[ii]); + } + + for (var ii = 0; ii < colorBuffers.length; ++ii) { + // The buffers should no longer be valid now that the VAOs are deleted + if(gl.isBuffer(colorBuffers[ii])) { + testFailed("buffer not properly cleaned up after VAO deletion"); + } + } +} + +function runBoundDeleteTests() { + debug("Testing using buffers that are deleted when attached to bound VAOs"); + + var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_position", "a_color"]); + gl.useProgram(program); + + var positionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + gl.bufferData( + gl.ARRAY_BUFFER, + new Float32Array([ + 1.0, 1.0, + -1.0, 1.0, + -1.0, -1.0, + 1.0, -1.0]), + gl.STATIC_DRAW); + + // Setup the color attrib + var colorBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array( + [ 255, 0, 0, 255, + 0, 255, 0, 255, + 0, 0, 255, 255, + 0, 255, 255, 255 + ]), gl.STATIC_DRAW); + + var vaos = []; + var elementBuffers = []; + for (var ii = 0; ii < 4; ++ii) { + var vao = ext.createVertexArrayOES(); + vaos.push(vao); + ext.bindVertexArrayOES(vao); + + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + gl.enableVertexAttribArray(0); + gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); + + var elementBuffer = gl.createBuffer(); + elementBuffers.push(elementBuffer); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer); + gl.bufferData( + gl.ELEMENT_ARRAY_BUFFER, + new Uint8Array([0, 1, 2, 0, 2, 3]), + gl.STATIC_DRAW); + + gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); + gl.enableVertexAttribArray(1); + gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 0, 0); + } + + // delete the color buffers AND the position buffer, that are bound to the current VAO + for (var ii = 0; ii < vaos.length; ++ii) { + ext.bindVertexArrayOES(vaos[ii]); + + gl.deleteBuffer(colorBuffer); + gl.deleteBuffer(positionBuffer); + + // The buffers should not be accessible at this point. Deleted objects that are bound + // in the current context undergo an automatic unbinding + var boundPositionBuffer = gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); + if(boundPositionBuffer == positionBuffer) { + testFailed("Position buffer should be automatically unbound when deleted"); + } + var boundColorBuffer = gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); + if(boundColorBuffer == colorBuffer) { + testFailed("Color buffer should be automatically unbound when deleted"); + } + + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Draw call should fail with unbound position and color buffers"); + + var isPositionBuffer = gl.isBuffer(positionBuffer); + var isColorBuffer = gl.isBuffer(colorBuffer); + + if(isPositionBuffer) testFailed("Position buffer should no longer exist after last ref removed"); + if(isColorBuffer) testFailed("Color buffer should no longer exist after last ref removed"); + } +} + +function runArrayBufferBindTests() { + debug(""); + debug("Testing that buffer bindings on VAOs don't affect default VAO ARRAY_BUFFER binding."); + + ext.bindVertexArrayOES(null); + + var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_color", "a_position"]); + gl.useProgram(program); + + // create shared element buffer + var elementBuffer = gl.createBuffer(); + // bind to default + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer); + gl.bufferData( + gl.ELEMENT_ARRAY_BUFFER, + new Uint8Array([0, 1, 2, 0, 2, 3]), + gl.STATIC_DRAW); + + // first create the buffers for no VAO draw. + var nonVAOColorBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, nonVAOColorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array( + [ 0, 255, 0, 255, + 0, 255, 0, 255, + 0, 255, 0, 255, + 0, 255, 0, 255, + ]), gl.STATIC_DRAW); + + // shared position buffer. + var positionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + gl.bufferData( + gl.ARRAY_BUFFER, + new Float32Array([ + 1.0, 1.0, + -1.0, 1.0, + -1.0, -1.0, + 1.0, -1.0]), + gl.STATIC_DRAW); + + // attach position buffer to default + gl.enableVertexAttribArray(1); + gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0); + + // now create VAO + var vao = ext.createVertexArrayOES(); + ext.bindVertexArrayOES(vao); + + // attach the position buffer VAO + gl.enableVertexAttribArray(1); + gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0); + + var vaoColorBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vaoColorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array( + [ 255, 0, 0, 255, + 255, 0, 0, 255, + 255, 0, 0, 255, + 255, 0, 0, 255, + ]), gl.STATIC_DRAW); + gl.enableVertexAttribArray(0); + gl.vertexAttribPointer(0, 4, gl.UNSIGNED_BYTE, true, 0, 0); + + // now set the buffer back to the nonVAOColorBuffer + gl.bindBuffer(gl.ARRAY_BUFFER, nonVAOColorBuffer); + + // bind to VAO + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer); + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0); + wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red"); + + // unbind VAO + ext.bindVertexArrayOES(null); + + // At this point the nonVAOColorBuffer should be still be bound. + // If the WebGL impl is emulating VAOs it must make sure + // it correctly restores this binding. + gl.enableVertexAttribArray(0); + gl.vertexAttribPointer(0, 4, gl.UNSIGNED_BYTE, true, 0, 0); + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0); + wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green"); +} + +debug(""); +var successfullyParsed = true; +</script> +<script src="../../js/js-test-post.js"></script> + +</body> +</html> |