| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
| <title>WebGL BindAttribLocation (Before Compile) Conformance Tests</title> |
| <script src="../../../resources/js-test.js"></script> |
| <script src="resources/webgl-test.js"></script> |
| </head> |
| <body> |
| <div id="description"></div> |
| <div id="console"></div> |
| <canvas style="border: 1px solid black;" id="canvas" width="50" height="50"></canvas> |
| <script id="vshader" type="text/something-not-javascript"> |
| attribute vec4 _glesVertex; |
| attribute vec4 vColor; |
| varying vec4 color; |
| void main() |
| { |
| gl_Position = _glesVertex; |
| color = vColor; |
| } |
| </script> |
| <script id="fshader" type="text/something-not-javascript"> |
| #ifdef GL_ES |
| precision highp float; |
| #endif |
| varying vec4 color; |
| void main() |
| { |
| gl_FragColor = color; |
| } |
| </script> |
| <script> |
| description("This test ensures WebGL implementations properly handle bindAttribLocation before compiling shaders."); |
| |
| if (window.internals) |
| window.internals.settings.setWebGLErrorsToConsoleEnabled(false); |
| |
| debug(""); |
| debug("Canvas.getContext"); |
| |
| var gl = create3DContext(document.getElementById("canvas")); |
| shouldBeNonNull(gl); |
| |
| function fail(x,y, buf, shouldBe) |
| { |
| var i = (y*50+x) * 4; |
| var reason = "pixel at ("+x+","+y+") is ("+buf[i]+","+buf[i+1]+","+buf[i+2]+","+buf[i+3]+"), should be "+shouldBe; |
| testFailed(reason); |
| } |
| |
| function pass() |
| { |
| testPassed("drawing is correct"); |
| } |
| |
| function loadShader(shaderType, shaderId) { |
| // Get the shader source. |
| var shaderSource = document.getElementById(shaderId).text; |
| |
| // Create the shader object |
| var shader = gl.createShader(shaderType); |
| if (shader == null) { |
| debug("*** Error: unable to create shader '"+shaderId+"'"); |
| return null; |
| } |
| |
| // Load the shader source |
| gl.shaderSource(shader, shaderSource); |
| |
| // Compile the shader |
| gl.compileShader(shader); |
| |
| // Check the compile status |
| var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); |
| if (!compiled) { |
| // Something went wrong during compilation; get the error |
| var error = gl.getShaderInfoLog(shader); |
| debug("*** Error compiling shader '"+shader+"':"+error); |
| gl.deleteShader(shader); |
| return null; |
| } |
| return shader; |
| } |
| |
| debug(""); |
| debug("Checking gl.bindAttribLocation."); |
| |
| var program = gl.createProgram(); |
| |
| // Bind _glesVertex BEFORE we comile the program. |
| gl.bindAttribLocation(program, 5, "_glesVertex"); |
| glErrorShouldBe(gl, gl.NO_ERROR, |
| "bindAttribLocation should return NO_ERROR when called before compiling shader."); |
| |
| var vs = loadShader(gl.VERTEX_SHADER, "vshader"); |
| var fs = loadShader(gl.FRAGMENT_SHADER, "fshader"); |
| gl.attachShader(program, vs); |
| gl.attachShader(program, fs); |
| |
| var positions = gl.createBuffer(); |
| gl.bindBuffer(gl.ARRAY_BUFFER, positions); |
| gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW); |
| |
| var colors = gl.createBuffer(); |
| gl.bindBuffer(gl.ARRAY_BUFFER, colors); |
| gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ |
| 0,1,0,1, |
| 0,1,0,1, |
| 0,1,0,1]), gl.STATIC_DRAW); |
| |
| function setBindLocations(colorLocation, positionLocation) { |
| gl.bindAttribLocation(program, colorLocation, "vColor"); |
| gl.linkProgram(program); |
| gl.useProgram(program); |
| var linked = (gl.getProgramParameter(program, gl.LINK_STATUS) != 0); |
| assertMsg(linked, "program linked successfully"); |
| |
| debug("_glesVertex:" + gl.getAttribLocation(program, "_glesVertex")) |
| debug("vColor :" + gl.getAttribLocation(program, "vColor")) |
| assertMsg(gl.getAttribLocation(program, "_glesVertex") == positionLocation, |
| "location of _glesVertex should be " + positionLocation); |
| assertMsg(gl.getAttribLocation(program, "vColor") == colorLocation, |
| "location of vColor should be " + colorLocation); |
| |
| var ploc = gl.getAttribLocation(program, "_glesVertex"); |
| var cloc = gl.getAttribLocation(program, "vColor"); |
| gl.bindBuffer(gl.ARRAY_BUFFER, positions); |
| gl.enableVertexAttribArray(positionLocation); |
| gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0); |
| gl.bindBuffer(gl.ARRAY_BUFFER, colors); |
| gl.enableVertexAttribArray(colorLocation); |
| gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0); |
| } |
| |
| function checkDraw(colorLocation, positionLocation, r, g, b, a) { |
| gl.clearColor(0, 0, 0, 1); |
| gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
| gl.drawArrays(gl.TRIANGLES, 0, 3); |
| |
| var width = 50; |
| var height = 50; |
| var buf = new Uint8Array(width * height * 4); |
| gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf); |
| |
| function checkPixel(x, y, r, g, b, a) { |
| var offset = (y * width + x) * 4; |
| if (buf[offset + 0] != r || |
| buf[offset + 1] != g || |
| buf[offset + 2] != b || |
| buf[offset + 3] != a) { |
| fail(x, y, buf, "(" + r + "," + g + "," + b + "," + a + ")"); |
| return false; |
| } |
| return true; |
| } |
| |
| // Test several locations |
| // First line should be all black |
| var success = true; |
| for (var i = 0; i < 50; ++i) |
| success = success && checkPixel(i, 0, 0, 0, 0, 255); |
| |
| // Line 15 should be red for at least 10 rgba pixels starting 20 pixels in |
| var offset = (15 * 50 + 20) * 4; |
| for (var i = 0; i < 10; ++i) |
| success = success && checkPixel(20 + i, 15, r, g, b, a); |
| |
| // Last line should be all black |
| for (var i = 0; i < 50; ++i) |
| success = success && checkPixel(i, 49, 0, 0, 0, 255); |
| |
| if (success) |
| pass(); |
| |
| gl.disableVertexAttribArray(positionLocation); |
| gl.disableVertexAttribArray(colorLocation); |
| } |
| |
| setBindLocations(2, 5); |
| checkDraw(2, 5, 0, 255, 0, 255); |
| |
| setBindLocations(1, 5); |
| gl.disableVertexAttribArray(0); |
| gl.vertexAttrib4f(0, 1, 0, 0, 1); |
| checkDraw(1, 5, 255, 0, 0, 255); |
| |
| glErrorShouldBe(gl, gl.NO_ERROR); |
| |
| debug(""); |
| |
| </script> |
| </body> |
| </html> |