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