2010-07-02 Zhenyao Mo <zmo@google.com>
[WebKit.git] / LayoutTests / fast / canvas / webgl / gl-uniform-arrays.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2   "http://www.w3.org/TR/html4/loose.dtd">
3 <html>
4 <head>
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>
10 </head>
11 <body>
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;
17     void main()
18     {
19         gl_Position = vPosition;
20     }
21 </script>
22
23 <script id="fshader" type="x-shader/x-fragment">
24     uniform $type color[3];
25     void main()
26     {
27         gl_FragColor = vec4(color[0]$elem, color[1]$elem, color[2]$elem, 1);
28     }
29 </script>
30 <script>
31 function loadShader(ctx, shaderType, shaderSource) {
32   // Create the shader object
33   var shader = ctx.createShader(shaderType);
34   if (shader == null) {
35     debug("*** Error: unable to create shader '"+shader+"'");
36     return null;
37   }
38
39   // Load the shader source
40   ctx.shaderSource(shader, shaderSource);
41
42   // Compile the shader
43   ctx.compileShader(shader);
44
45   // Check the compile status
46   var compiled = ctx.getShaderParameter(shader, ctx.COMPILE_STATUS);
47   if (!compiled) {
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);
52     return null;
53   }
54
55   return shader;
56 }
57
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);
66   if (!linked) {
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);
71     program = null;
72   }
73 //  ctx.deleteShader(fShader);
74 //  ctx.deleteShader(vShader);
75   return program;
76 }
77
78 description("This test ensures WebGL implementations handle uniform arrays correctly.");
79
80 debug("");
81
82 var gl = create3DContext(document.getElementById("example"));
83
84 var vSrc = document.getElementById("vshader").text;
85 var fTemplate = document.getElementById("fshader").text;
86
87 var typeInfos = [
88   { type: 'float',
89     jsTypeOf: 'number',
90     setter: 'uniform1fv',
91     elem: '',
92     numSrcValues: 3,
93     badSet: function(loc) {
94       gl.uniform2fv(loc, [1, 2]);
95     },
96     srcValueAsString: function(index, srcValues) {
97       return srcValues[index].toString();
98     },
99     returnValueAsString: function(value) {
100       return value === null ? 'null' : value.toString();
101     },
102     checkType: function(value) {
103       return typeof values === 'number';
104     },
105     checkValue: function(typeInfo, index, value) {
106       return typeInfo.srcValues[index] == value;
107     },
108     srcValues: [16, 15, 14],
109     srcValuesBad: [],
110   },
111   { type: 'vec2',
112     jsTypeOf: 'Float32Array',
113     setter: 'uniform2fv',
114     elem: '[1]',
115     numSrcValues: 3,
116     badSet: function(loc) {
117       gl.uniform1fv(loc, [2]);
118     },
119     srcValueAsString: function(index, srcValues) {
120       return "[" + srcValues[index * 2 + 0].toString() + ", " +
121                    srcValues[index * 2 + 1].toString() + "]";
122     },
123     returnValueAsString: function(value) {
124       return value === null ? 'null' : ("[" + value[0] + ", " + value[1] + "]");
125     },
126     checkType: function(value) {
127       return typeof values.length === 'number' &&
128              values.length == 2;
129     },
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];
134     },
135     srcValues: [16, 15, 14, 13, 12, 11],
136     srcValuesBad: [16],
137   },
138   { type: 'vec3',
139     jsTypeOf: 'Float32Array',
140     setter: 'uniform3fv',
141     elem: '[2]',
142     numSrcValues: 3,
143     badSet: function(loc) {
144       gl.uniform1fv(loc, [2]);
145     },
146     srcValueAsString: function(index, srcValues) {
147       return "[" + srcValues[index * 3 + 0].toString() + ", " +
148                    srcValues[index * 3 + 1].toString() + ", " +
149                    srcValues[index * 3 + 2].toString() + "]";
150     },
151     returnValueAsString: function(value) {
152       return value === null ? 'null' :
153           ("[" + value[0] + ", " + value[1] + ", " + value[2] + "]");
154     },
155     checkType: function(value) {
156       return typeof values.length === 'number' &&
157              values.length == 3;
158     },
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];
164     },
165     srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8],
166     srcValuesBad: [16, 15],
167   },
168   { type: 'vec4',
169     jsTypeOf: 'Float32Array',
170     setter: 'uniform4fv',
171     elem: '[3]',
172     numSrcValues: 3,
173     badSet: function(loc) {
174       gl.uniform1fv(loc, [2]);
175     },
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() + "]";
181     },
182     returnValueAsString: function(value) {
183       return value === null ? 'null' :
184           ("[" + value[0] + ", " + value[1] +
185            ", " + value[2] + ", " + value[3] + "]");
186     },
187     checkType: function(value) {
188       return typeof values.length === 'number' &&
189              values.length == 4;
190     },
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];
197     },
198     srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
199     srcValuesBad: [16, 15, 14],
200   }
201 ];
202
203 for (var tt = 0; tt < typeInfos.length; ++tt) {
204   var typeInfo = typeInfos[tt];
205   debug("");
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);
211
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;
220
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");
225
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) + ")");
250   }
251   typeInfo.badSet(loc);
252   assertMsg(gl.getError() == gl.INVALID_OPERATION,
253             "using the wrong size of gl.Uniform fails");
254
255   gl.useProgram(null);
256   assertMsg(gl.getError() == gl.NO_ERROR,
257             "can call gl.useProgram(null)");
258 }
259 debug("");
260 successfullyParsed = true;
261
262 </script>
263 <script src="../../js/resources/js-test-post.js"></script>
264
265 <script>
266 </script>
267
268 </body>
269 </html>