| OLD | NEW |
| (Empty) |
| 1 <!-- | |
| 2 Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 3 Use of this source code is governed by a BSD-style license that can be | |
| 4 found in the LICENSE file. | |
| 5 --> | |
| 6 <!DOCTYPE html> | |
| 7 <html> | |
| 8 <head> | |
| 9 <meta charset="utf-8"> | |
| 10 <title>WebGL uniform array Conformance Tests</title> | |
| 11 <link rel="stylesheet" href="../resources/js-test-style.css"/> | |
| 12 <script src="../resources/js-test-pre.js"></script> | |
| 13 <script src="resources/webgl-test.js"></script> | |
| 14 </head> | |
| 15 <body> | |
| 16 <div id="description"></div> | |
| 17 <div id="console"></div> | |
| 18 <canvas id="example" width="2" height="2"> </canvas> | |
| 19 <script id="vshader" type="x-shader/x-vertex"> | |
| 20 attribute vec4 vPosition; | |
| 21 void main() | |
| 22 { | |
| 23 gl_Position = vPosition; | |
| 24 } | |
| 25 </script> | |
| 26 | |
| 27 <script id="fshader" type="x-shader/x-fragment"> | |
| 28 precision mediump float; | |
| 29 uniform $type color[3]; | |
| 30 void main() | |
| 31 { | |
| 32 gl_FragColor = vec4(color[0]$elem, color[1]$elem, color[2]$elem, 1); | |
| 33 } | |
| 34 </script> | |
| 35 <script> | |
| 36 function loadShader(ctx, shaderType, shaderSource) { | |
| 37 // Create the shader object | |
| 38 var shader = ctx.createShader(shaderType); | |
| 39 if (shader == null) { | |
| 40 debug("*** Error: unable to create shader '"+shader+"'"); | |
| 41 return null; | |
| 42 } | |
| 43 | |
| 44 // Load the shader source | |
| 45 ctx.shaderSource(shader, shaderSource); | |
| 46 | |
| 47 // Compile the shader | |
| 48 ctx.compileShader(shader); | |
| 49 | |
| 50 // Check the compile status | |
| 51 var compiled = ctx.getShaderParameter(shader, ctx.COMPILE_STATUS); | |
| 52 if (!compiled) { | |
| 53 // Something went wrong during compilation; get the error | |
| 54 var error = ctx.getShaderInfoLog(shader); | |
| 55 debug("*** Error compiling shader '"+shader+"':"+error); | |
| 56 ctx.deleteShader(shader); | |
| 57 return null; | |
| 58 } | |
| 59 | |
| 60 return shader; | |
| 61 } | |
| 62 | |
| 63 function loadProgram(ctx, vertexShaderSrc, fragmentShaderSrc) { | |
| 64 var program = ctx.createProgram(); | |
| 65 var vShader = loadShader(ctx, ctx.VERTEX_SHADER, vertexShaderSrc) | |
| 66 var fShader = loadShader(ctx, ctx.FRAGMENT_SHADER, fragmentShaderSrc); | |
| 67 ctx.attachShader(program, vShader); | |
| 68 ctx.attachShader(program, fShader); | |
| 69 ctx.linkProgram(program); | |
| 70 var linked = ctx.getProgramParameter(program, ctx.LINK_STATUS); | |
| 71 if (!linked) { | |
| 72 // something went wrong with the link | |
| 73 var error = ctx.getProgramInfoLog (ctx.program); | |
| 74 debug("Error in program linking:" + error); | |
| 75 ctx.deleteProgram(ctx.program); | |
| 76 program = null; | |
| 77 } | |
| 78 // ctx.deleteShader(fShader); | |
| 79 // ctx.deleteShader(vShader); | |
| 80 return program; | |
| 81 } | |
| 82 | |
| 83 description("This test ensures WebGL implementations handle uniform arrays corre
ctly."); | |
| 84 | |
| 85 debug(""); | |
| 86 | |
| 87 var gl = create3DContext(document.getElementById("example")); | |
| 88 | |
| 89 var vSrc = document.getElementById("vshader").text; | |
| 90 var fTemplate = document.getElementById("fshader").text; | |
| 91 | |
| 92 var typeInfos = [ | |
| 93 { type: 'float', | |
| 94 jsTypeOf: 'number', | |
| 95 setter: 'uniform1fv', | |
| 96 elem: '', | |
| 97 numSrcValues: 3, | |
| 98 invalidSet: function(loc) { | |
| 99 gl.uniform2fv(loc, [1, 2]); | |
| 100 }, | |
| 101 srcValueAsString: function(index, srcValues) { | |
| 102 return srcValues[index].toString(); | |
| 103 }, | |
| 104 returnValueAsString: function(value) { | |
| 105 return value === null ? 'null' : value.toString(); | |
| 106 }, | |
| 107 checkType: function(value) { | |
| 108 return typeof value === 'number'; | |
| 109 }, | |
| 110 checkValue: function(typeInfo, index, value) { | |
| 111 return typeInfo.srcValues[index] == value; | |
| 112 }, | |
| 113 srcValues: [16, 15, 14], | |
| 114 srcValuesLess: [], | |
| 115 srcValuesNonMultiple: null, | |
| 116 }, | |
| 117 { type: 'vec2', | |
| 118 jsTypeOf: 'Float32Array', | |
| 119 setter: 'uniform2fv', | |
| 120 elem: '[1]', | |
| 121 numSrcValues: 3, | |
| 122 invalidSet: function(loc) { | |
| 123 gl.uniform1fv(loc, [2]); | |
| 124 }, | |
| 125 illegalSet: function(loc) { | |
| 126 gl.uniform1fv(loc, 2); | |
| 127 }, | |
| 128 srcValueAsString: function(index, srcValues) { | |
| 129 return "[" + srcValues[index * 2 + 0].toString() + ", " + | |
| 130 srcValues[index * 2 + 1].toString() + "]"; | |
| 131 }, | |
| 132 returnValueAsString: function(value) { | |
| 133 return value === null ? 'null' : ("[" + value[0] + ", " + value[1] + "]"); | |
| 134 }, | |
| 135 checkType: function(value) { | |
| 136 return value && | |
| 137 typeof value.length === 'number' && | |
| 138 value.length == 2; | |
| 139 }, | |
| 140 checkValue: function(typeInfo, index, value) { | |
| 141 return value !== null && | |
| 142 typeInfo.srcValues[index * 2 + 0] == value[0] && | |
| 143 typeInfo.srcValues[index * 2 + 1] == value[1]; | |
| 144 }, | |
| 145 srcValues: [16, 15, 14, 13, 12, 11], | |
| 146 srcValuesLess: [16], | |
| 147 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10], | |
| 148 }, | |
| 149 { type: 'vec3', | |
| 150 jsTypeOf: 'Float32Array', | |
| 151 setter: 'uniform3fv', | |
| 152 elem: '[2]', | |
| 153 numSrcValues: 3, | |
| 154 invalidSet: function(loc) { | |
| 155 gl.uniform1fv(loc, [2]); | |
| 156 }, | |
| 157 illegalSet: function(loc) { | |
| 158 gl.uniform1fv(loc, 2); | |
| 159 }, | |
| 160 srcValueAsString: function(index, srcValues) { | |
| 161 return "[" + srcValues[index * 3 + 0].toString() + ", " + | |
| 162 srcValues[index * 3 + 1].toString() + ", " + | |
| 163 srcValues[index * 3 + 2].toString() + "]"; | |
| 164 }, | |
| 165 returnValueAsString: function(value) { | |
| 166 return value === null ? 'null' : | |
| 167 ("[" + value[0] + ", " + value[1] + ", " + value[2] + "]"); | |
| 168 }, | |
| 169 checkType: function(value) { | |
| 170 return value && | |
| 171 typeof value.length === 'number' && | |
| 172 value.length == 3; | |
| 173 }, | |
| 174 checkValue: function(typeInfo, index, value) { | |
| 175 return value !== null && | |
| 176 typeInfo.srcValues[index * 3 + 0] == value[0] && | |
| 177 typeInfo.srcValues[index * 3 + 1] == value[1] && | |
| 178 typeInfo.srcValues[index * 3 + 2] == value[2]; | |
| 179 }, | |
| 180 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8], | |
| 181 srcValuesLess: [16, 15], | |
| 182 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7], | |
| 183 }, | |
| 184 { type: 'vec4', | |
| 185 jsTypeOf: 'Float32Array', | |
| 186 setter: 'uniform4fv', | |
| 187 elem: '[3]', | |
| 188 numSrcValues: 3, | |
| 189 invalidSet: function(loc) { | |
| 190 gl.uniform1fv(loc, [2]); | |
| 191 }, | |
| 192 illegalSet: function(loc) { | |
| 193 gl.uniform1fv(loc, 2); | |
| 194 }, | |
| 195 srcValueAsString: function(index, srcValues) { | |
| 196 return "[" + srcValues[index * 4 + 0].toString() + ", " + | |
| 197 srcValues[index * 4 + 1].toString() + ", " + | |
| 198 srcValues[index * 4 + 2].toString() + ", " + | |
| 199 srcValues[index * 4 + 3].toString() + "]"; | |
| 200 }, | |
| 201 returnValueAsString: function(value) { | |
| 202 return value === null ? 'null' : | |
| 203 ("[" + value[0] + ", " + value[1] + | |
| 204 ", " + value[2] + ", " + value[3] + "]"); | |
| 205 }, | |
| 206 checkType: function(value) { | |
| 207 return value && | |
| 208 typeof value.length === 'number' && | |
| 209 value.length == 4; | |
| 210 }, | |
| 211 checkValue: function(typeInfo, index, value) { | |
| 212 return value !== null && | |
| 213 typeInfo.srcValues[index * 4 + 0] == value[0] && | |
| 214 typeInfo.srcValues[index * 4 + 1] == value[1] && | |
| 215 typeInfo.srcValues[index * 4 + 2] == value[2] && | |
| 216 typeInfo.srcValues[index * 4 + 3] == value[3]; | |
| 217 }, | |
| 218 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], | |
| 219 srcValuesLess: [16, 15, 14], | |
| 220 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4], | |
| 221 } | |
| 222 ]; | |
| 223 | |
| 224 for (var tt = 0; tt < typeInfos.length; ++tt) { | |
| 225 var typeInfo = typeInfos[tt]; | |
| 226 debug(""); | |
| 227 debug("check " + typeInfo.type); | |
| 228 var fSrc = fTemplate.replace(/\$type/g, typeInfo.type). | |
| 229 replace(/\$elem/g, typeInfo.elem); | |
| 230 //debug("fSrc: " + fSrc); | |
| 231 var program = loadProgram(gl, vSrc, fSrc); | |
| 232 | |
| 233 var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); | |
| 234 assertMsg(numUniforms == 1, "1 uniform found"); | |
| 235 var info = gl.getActiveUniform(program, 0); | |
| 236 assertMsg(info.name == "color[0]", | |
| 237 "uniform name is 'color[0]' not 'color' as per OpenGL ES 2.0.24 sect
ion 2.10"); | |
| 238 var loc = gl.getUniformLocation(program, "color[0]"); | |
| 239 var srcValues = typeInfo.srcValues; | |
| 240 var srcValuesLess = typeInfo.srcValuesLess; | |
| 241 var srcValuesNonMultiple = typeInfo.srcValuesNonMultiple; | |
| 242 | |
| 243 // Try setting the value before using the program | |
| 244 gl[typeInfo.setter](loc, srcValues); | |
| 245 glErrorShouldBe(gl, gl.INVALID_OPERATION, | |
| 246 "should fail if there is no current program"); | |
| 247 | |
| 248 gl.useProgram(program); | |
| 249 gl[typeInfo.setter](loc, srcValuesLess); | |
| 250 glErrorShouldBe(gl, gl.INVALID_VALUE, | |
| 251 "should fail with insufficient array size with gl." + typeInfo
.setter); | |
| 252 if (srcValuesNonMultiple) { | |
| 253 gl[typeInfo.setter](loc, srcValuesNonMultiple); | |
| 254 glErrorShouldBe(gl, gl.INVALID_VALUE, | |
| 255 "should fail with non-multiple array size with gl." + typeIn
fo.setter); | |
| 256 } | |
| 257 gl[typeInfo.setter](loc, srcValues); | |
| 258 glErrorShouldBe(gl, gl.NO_ERROR, | |
| 259 "can set an array of uniforms with gl." + typeInfo.setter); | |
| 260 var values = gl.getUniform(program, loc); | |
| 261 glErrorShouldBe(gl, gl.NO_ERROR, | |
| 262 "can call gl.getUniform"); | |
| 263 assertMsg(typeInfo.checkType(values), | |
| 264 "gl.getUniform returns the correct type."); | |
| 265 for (var ii = 0; ii < typeInfo.numSrcValues; ++ii) { | |
| 266 var elemLoc = gl.getUniformLocation(program, "color[" + ii + "]"); | |
| 267 glErrorShouldBe(gl, gl.NO_ERROR, | |
| 268 "can get location of element " + ii + | |
| 269 " of array from gl.getUniformLocation"); | |
| 270 var value = gl.getUniform(program, elemLoc); | |
| 271 glErrorShouldBe(gl, gl.NO_ERROR, | |
| 272 "can get value of element " + ii + " of array from gl.getUni
form"); | |
| 273 assertMsg(typeInfo.checkValue(typeInfo, ii, value), | |
| 274 "value put in (" + typeInfo.srcValueAsString(ii, srcValues) + | |
| 275 ") matches value pulled out (" + | |
| 276 typeInfo.returnValueAsString(value) + ")"); | |
| 277 } | |
| 278 typeInfo.invalidSet(loc); | |
| 279 glErrorShouldBe(gl, gl.INVALID_OPERATION, | |
| 280 "using the wrong size of gl.Uniform fails"); | |
| 281 var exceptionCaught = false; | |
| 282 if (typeInfo.illegalSet) { | |
| 283 try { | |
| 284 typeInfo.illegalSet(loc); | |
| 285 } catch (e) { | |
| 286 exceptionCaught = true; | |
| 287 } | |
| 288 assertMsg(exceptionCaught, "passing non-array to glUniform*fv should throw T
ypeError"); | |
| 289 } | |
| 290 | |
| 291 gl.useProgram(null); | |
| 292 glErrorShouldBe(gl, gl.NO_ERROR, | |
| 293 "can call gl.useProgram(null)"); | |
| 294 } | |
| 295 debug(""); | |
| 296 successfullyParsed = true; | |
| 297 | |
| 298 </script> | |
| 299 <script src="../resources/js-test-post.js"></script> | |
| 300 | |
| 301 </body> | |
| 302 </html> | |
| OLD | NEW |