gl-bindAttribLocation-matrix.html (4573B)
1 <!-- 2 Copyright (c) 2019 The Khronos Group Inc. 3 Use of this source code is governed by an MIT-style license that can be 4 found in the LICENSE.txt file. 5 --> 6 <!DOCTYPE html> 7 <html> 8 <head> 9 <meta charset="utf-8"> 10 <link rel="stylesheet" href="../../resources/js-test-style.css"/> 11 <script src="../../js/js-test-pre.js"></script> 12 <script src="../../js/webgl-test-utils.js"></script> 13 <title>WebGL bindAttribLocation with Matrix Attributes Conformance Test</title> 14 </head> 15 <body> 16 <div id="description"></div> 17 <div id="console"></div> 18 <canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas> 19 <script> 20 "use strict"; 21 description("This test verifies that vectors placed via bindAttribLocation right after matricies will fail if there is insufficient room for the matrix."); 22 23 var wtu = WebGLTestUtils; 24 var canvas = document.getElementById("canvas"); 25 var gl = wtu.create3DContext(canvas, {antialias: false}); 26 27 // Make sure we have room for at least a mat4. 28 var maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); 29 debug('MAX_VERTEX_ATTRIBUTES is ' + maxAttributes); 30 shouldBeGreaterThanOrEqual('maxAttributes', '4'); 31 32 var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER); 33 34 // Given a matrix dimension, load a vertex shader with a matrix of that dimension 35 // and a vector. Ensure that both the vector and matrix are active attributes. 36 // Return the compiled vertex shader. 37 function loadVertexShader(numMatrixDimensions) { 38 var strVertexShader = 39 'attribute mat' + numMatrixDimensions + ' matrix;\n' + 40 'attribute vec' + numMatrixDimensions + ' vector;\n' + 41 'void main(void) { gl_Position = vec4(vector*matrix'; 42 // Ensure the vec4 has the correct number of dimensions in order to be assignable 43 // to gl_Position. 44 for (var ii = numMatrixDimensions; ii < 4; ++ii) { 45 strVertexShader += ",0.0"; 46 } 47 strVertexShader += ");}\n"; 48 return wtu.loadShader(gl, strVertexShader, gl.VERTEX_SHADER); 49 } 50 51 // Given a vertex shader, matrix location and vector location, create and link 52 // a program with glFragmentShader and a vertex shader returned by loadVertexShader 53 // attached. Bind the matrix to matrixLocation and the vector to vectorLocation. 54 // Return whether the link was successful. 55 function createAndLinkProgram(glVertexShader, matrixLocation, vectorLocation) { 56 var glProgram = gl.createProgram(); 57 gl.bindAttribLocation(glProgram, matrixLocation, 'matrix'); 58 gl.bindAttribLocation(glProgram, vectorLocation, 'vector'); 59 gl.attachShader(glProgram, glVertexShader); 60 gl.attachShader(glProgram, glFragmentShader); 61 gl.linkProgram(glProgram); 62 return gl.getProgramParameter(glProgram, gl.LINK_STATUS); 63 } 64 65 // For each matrix dimension (mat2, mat3 and mat4) 66 for (var mm = 2; mm <= 4; ++mm) { 67 debug('Testing ' + mm + ' dimensional matrices'); 68 var glVertexShader = loadVertexShader(mm); 69 // Per the WebGL spec: "LinkProgram will fail if the attribute bindings assigned 70 // by bindAttribLocation do not leave enough space to assign a location for an 71 // active matrix attribute which requires multiple contiguous generic attributes." 72 // We will test this by placing the vector after the matrix attribute such that there 73 // is not enough room for the matrix. Vertify the link operation fails. 74 75 // Run the test for each available attribute slot. Go to maxAttributes-mm to leave enough room 76 // for the matrix itself. Leave another slot open for the vector following the matrix. 77 for (var pp = 0; pp <= maxAttributes - mm - 1; ++pp) { 78 // For each matrix dimension, bind the vector right after the matrix such that we leave 79 // insufficient room for the matrix. Verify doing this will fail the link operation. 80 for (var ll = 0; ll < mm; ++ll) { 81 var vectorLocation = pp + ll; 82 assertMsg(!createAndLinkProgram(glVertexShader, /*matrixLocation*/pp, vectorLocation), 83 "Matrix with location " + pp + " and vector with location " + vectorLocation + " should not link."); 84 } 85 // Ensure that once we have left enough room for the matrix, the program links successfully. 86 var vectorLocation = pp + ll; 87 assertMsg(createAndLinkProgram(glVertexShader, /*matrixLocation*/pp, vectorLocation), 88 "Matrix with location " + pp + " and vector with location " + vectorLocation + " should link."); 89 debug(''); 90 } 91 debug(''); 92 } 93 94 var successfullyParsed = true; 95 </script> 96 <script src="../../js/js-test-post.js"></script> 97 </body> 98 </html>