1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6 <title>WebGL uniform array Conformance Tests</title>
7 <link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
8 <script src="../../js/resources/js-test-pre.js"></script>
9 <script src="resources/webgl-test.js"></script>
12 <div id="description"></div>
13 <div id="console"></div>
14 <canvas id="example" width="2" height="2"> </canvas>
15 <script id="vshader" type="x-shader/x-vertex">
16 attribute vec4 vPosition;
19 gl_Position = vPosition;
23 <script id="fshader" type="x-shader/x-fragment">
24 uniform $type color[3];
27 gl_FragColor = vec4(color[0]$elem, color[1]$elem, color[2]$elem, 1);
31 function loadShader(ctx, shaderType, shaderSource) {
32 // Create the shader object
33 var shader = ctx.createShader(shaderType);
35 debug("*** Error: unable to create shader '"+shader+"'");
39 // Load the shader source
40 ctx.shaderSource(shader, shaderSource);
43 ctx.compileShader(shader);
45 // Check the compile status
46 var compiled = ctx.getShaderParameter(shader, ctx.COMPILE_STATUS);
48 // Something went wrong during compilation; get the error
49 var error = ctx.getShaderInfoLog(shader);
50 debug("*** Error compiling shader '"+shader+"':"+error);
51 ctx.deleteShader(shader);
58 function loadProgram(ctx, vertexShaderSrc, fragmentShaderSrc) {
59 var program = ctx.createProgram();
60 var vShader = loadShader(ctx, ctx.VERTEX_SHADER, vertexShaderSrc)
61 var fShader = loadShader(ctx, ctx.FRAGMENT_SHADER, fragmentShaderSrc);
62 ctx.attachShader(program, vShader);
63 ctx.attachShader(program, fShader);
64 ctx.linkProgram(program);
65 var linked = ctx.getProgramParameter(program, ctx.LINK_STATUS);
67 // something went wrong with the link
68 var error = ctx.getProgramInfoLog (ctx.program);
69 debug("Error in program linking:" + error);
70 ctx.deleteProgram(ctx.program);
73 // ctx.deleteShader(fShader);
74 // ctx.deleteShader(vShader);
78 description("This test ensures WebGL implementations handle uniform arrays correctly.");
82 var gl = create3DContext(document.getElementById("example"));
84 var vSrc = document.getElementById("vshader").text;
85 var fTemplate = document.getElementById("fshader").text;
93 badSet: function(loc) {
94 gl.uniform2fv(loc, [1, 2]);
96 srcValueAsString: function(index, srcValues) {
97 return srcValues[index].toString();
99 returnValueAsString: function(value) {
100 return value === null ? 'null' : value.toString();
102 checkType: function(value) {
103 return typeof values === 'number';
105 checkValue: function(typeInfo, index, value) {
106 return typeInfo.srcValues[index] == value;
108 srcValues: [16, 15, 14],
112 jsTypeOf: 'Float32Array',
113 setter: 'uniform2fv',
116 badSet: function(loc) {
117 gl.uniform1fv(loc, [2]);
119 srcValueAsString: function(index, srcValues) {
120 return "[" + srcValues[index * 2 + 0].toString() + ", " +
121 srcValues[index * 2 + 1].toString() + "]";
123 returnValueAsString: function(value) {
124 return value === null ? 'null' : ("[" + value[0] + ", " + value[1] + "]");
126 checkType: function(value) {
127 return typeof values.length === 'number' &&
130 checkValue: function(typeInfo, index, value) {
131 return value !== null &&
132 typeInfo.srcValues[index * 2 + 0] == value[0] &&
133 typeInfo.srcValues[index * 2 + 1] == value[1];
135 srcValues: [16, 15, 14, 13, 12, 11],
139 jsTypeOf: 'Float32Array',
140 setter: 'uniform3fv',
143 badSet: function(loc) {
144 gl.uniform1fv(loc, [2]);
146 srcValueAsString: function(index, srcValues) {
147 return "[" + srcValues[index * 3 + 0].toString() + ", " +
148 srcValues[index * 3 + 1].toString() + ", " +
149 srcValues[index * 3 + 2].toString() + "]";
151 returnValueAsString: function(value) {
152 return value === null ? 'null' :
153 ("[" + value[0] + ", " + value[1] + ", " + value[2] + "]");
155 checkType: function(value) {
156 return typeof values.length === 'number' &&
159 checkValue: function(typeInfo, index, value) {
160 return value !== null &&
161 typeInfo.srcValues[index * 3 + 0] == value[0] &&
162 typeInfo.srcValues[index * 3 + 1] == value[1] &&
163 typeInfo.srcValues[index * 3 + 2] == value[2];
165 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8],
166 srcValuesBad: [16, 15],
169 jsTypeOf: 'Float32Array',
170 setter: 'uniform4fv',
173 badSet: function(loc) {
174 gl.uniform1fv(loc, [2]);
176 srcValueAsString: function(index, srcValues) {
177 return "[" + srcValues[index * 4 + 0].toString() + ", " +
178 srcValues[index * 4 + 1].toString() + ", " +
179 srcValues[index * 4 + 2].toString() + ", " +
180 srcValues[index * 4 + 3].toString() + "]";
182 returnValueAsString: function(value) {
183 return value === null ? 'null' :
184 ("[" + value[0] + ", " + value[1] +
185 ", " + value[2] + ", " + value[3] + "]");
187 checkType: function(value) {
188 return typeof values.length === 'number' &&
191 checkValue: function(typeInfo, index, value) {
192 return value !== null &&
193 typeInfo.srcValues[index * 4 + 0] == value[0] &&
194 typeInfo.srcValues[index * 4 + 1] == value[1] &&
195 typeInfo.srcValues[index * 4 + 2] == value[2] &&
196 typeInfo.srcValues[index * 4 + 3] == value[3];
198 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
199 srcValuesBad: [16, 15, 14],
203 for (var tt = 0; tt < typeInfos.length; ++tt) {
204 var typeInfo = typeInfos[tt];
206 debug("check " + typeInfo.type);
207 var fSrc = fTemplate.replace(/\$type/g, typeInfo.type).
208 replace(/\$elem/g, typeInfo.elem);
209 //debug("fSrc: " + fSrc);
210 var program = loadProgram(gl, vSrc, fSrc);
212 var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
213 assertMsg(numUniforms == 1, "1 uniform found");
214 var info = gl.getActiveUniform(program, 0);
215 assertMsg(info.name == "color[0]",
216 "uniform name is 'color[0]' not 'color' as per OpenGL ES 2.0.24 section 2.10");
217 var loc = gl.getUniformLocation(program, "color");
218 var srcValues = typeInfo.srcValues;
219 var srcValuesBad = typeInfo.srcValuesBad;
221 // Try setting the value before using the program
222 gl[typeInfo.setter](loc, srcValues);
223 assertMsg(gl.getError() == gl.INVALID_OPERATION,
224 "should fail if there is no current program");
226 gl.useProgram(program);
227 gl[typeInfo.setter](loc, srcValuesBad);
228 assertMsg(gl.getError() == gl.INVALID_VALUE,
229 "should fail with insufficient array size with gl." + typeInfo.setter);
230 gl[typeInfo.setter](loc, srcValues);
231 assertMsg(gl.getError() == gl.NO_ERROR,
232 "can set an array of uniforms with gl." + typeInfo.setter);
233 var values = gl.getUniform(program, loc);
234 assertMsg(gl.getError() == gl.NO_ERROR,
235 "can call gl.getUniform");
236 assertMsg(typeInfo.checkType(values),
237 "gl.getUniform returns the correct type.");
238 for (var ii = 0; ii < typeInfo.numSrcValues; ++ii) {
239 var elemLoc = gl.getUniformLocation(program, "color[" + ii + "]");
240 assertMsg(gl.getError() == gl.NO_ERROR,
241 "can get location of element " + ii +
242 " of array from gl.getUniformLocation");
243 var value = gl.getUniform(program, elemLoc);
244 assertMsg(gl.getError() == gl.NO_ERROR,
245 "can get value of element " + ii + " of array from gl.getUniform");
246 assertMsg(typeInfo.checkValue(typeInfo, ii, value),
247 "value put in (" + typeInfo.srcValueAsString(ii, srcValues) +
248 ") matches value pulled out (" +
249 typeInfo.returnValueAsString(value) + ")");
251 typeInfo.badSet(loc);
252 assertMsg(gl.getError() == gl.INVALID_OPERATION,
253 "using the wrong size of gl.Uniform fails");
256 assertMsg(gl.getError() == gl.NO_ERROR,
257 "can call gl.useProgram(null)");
260 successfullyParsed = true;
263 <script src="../../js/resources/js-test-post.js"></script>