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 <script src=
"../../../resources/js-test.js"></script>
8 <script src=
"resources/webgl-test.js"></script>
11 <div id=
"description"></div>
12 <div id=
"console"></div>
13 <canvas id=
"example" width=
"2" height=
"2"> </canvas>
14 <script id=
"vshader" type=
"x-shader/x-vertex">
15 attribute vec4 vPosition;
18 gl_Position = vPosition;
22 <script id=
"fshader" type=
"x-shader/x-fragment">
24 precision mediump float;
26 uniform $type color[
3];
29 gl_FragColor = vec4(color[
0]$elem, color[
1]$elem, color[
2]$elem,
1);
33 function loadShader(ctx
, shaderType
, shaderSource
) {
34 // Create the shader object
35 var shader
= ctx
.createShader(shaderType
);
37 debug("*** Error: unable to create shader '"+shader
+"'");
41 // Load the shader source
42 ctx
.shaderSource(shader
, shaderSource
);
45 ctx
.compileShader(shader
);
47 // Check the compile status
48 var compiled
= ctx
.getShaderParameter(shader
, ctx
.COMPILE_STATUS
);
50 // Something went wrong during compilation; get the error
51 var error
= ctx
.getShaderInfoLog(shader
);
52 debug("*** Error compiling shader '"+shader
+"':"+error
);
53 ctx
.deleteShader(shader
);
60 function loadProgram(ctx
, vertexShaderSrc
, fragmentShaderSrc
) {
61 var program
= ctx
.createProgram();
62 var vShader
= loadShader(ctx
, ctx
.VERTEX_SHADER
, vertexShaderSrc
)
63 var fShader
= loadShader(ctx
, ctx
.FRAGMENT_SHADER
, fragmentShaderSrc
);
64 ctx
.attachShader(program
, vShader
);
65 ctx
.attachShader(program
, fShader
);
66 ctx
.linkProgram(program
);
67 var linked
= ctx
.getProgramParameter(program
, ctx
.LINK_STATUS
);
69 // something went wrong with the link
70 var error
= ctx
.getProgramInfoLog (ctx
.program
);
71 debug("Error in program linking:" + error
);
72 ctx
.deleteProgram(ctx
.program
);
75 // ctx.deleteShader(fShader);
76 // ctx.deleteShader(vShader);
80 description("This test ensures WebGL implementations handle uniform arrays correctly.");
85 window
.internals
.settings
.setWebGLErrorsToConsoleEnabled(false);
87 var gl
= create3DContext(document
.getElementById("example"));
89 var vSrc
= document
.getElementById("vshader").text
;
90 var fTemplate
= document
.getElementById("fshader").text
;
98 invalidSet: function(loc
) {
99 gl
.uniform2fv(loc
, [1, 2]);
101 srcValueAsString: function(index
, srcValues
) {
102 return srcValues
[index
].toString();
104 returnValueAsString: function(value
) {
105 return value
=== null ? 'null' : value
.toString();
107 checkType: function(value
) {
108 return typeof value
=== 'number';
110 checkValue: function(typeInfo
, index
, value
) {
111 return typeInfo
.srcValues
[index
] == value
;
113 srcValues
: [16, 15, 14],
115 srcValuesNonMultiple
: null,
118 jsTypeOf
: 'Float32Array',
119 setter
: 'uniform2fv',
122 invalidSet: function(loc
) {
123 gl
.uniform1fv(loc
, [2]);
125 illegalSet: function(loc
) {
126 gl
.uniform1fv(loc
, 2);
128 srcValueAsString: function(index
, srcValues
) {
129 return "[" + srcValues
[index
* 2 + 0].toString() + ", " +
130 srcValues
[index
* 2 + 1].toString() + "]";
132 returnValueAsString: function(value
) {
133 return value
=== null ? 'null' : ("[" + value
[0] + ", " + value
[1] + "]");
135 checkType: function(value
) {
137 typeof value
.length
=== 'number' &&
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];
145 srcValues
: [16, 15, 14, 13, 12, 11],
147 srcValuesNonMultiple
: [16, 15, 14, 13, 12, 11, 10],
150 jsTypeOf
: 'Float32Array',
151 setter
: 'uniform3fv',
154 invalidSet: function(loc
) {
155 gl
.uniform1fv(loc
, [2]);
157 illegalSet: function(loc
) {
158 gl
.uniform1fv(loc
, 2);
160 srcValueAsString: function(index
, srcValues
) {
161 return "[" + srcValues
[index
* 3 + 0].toString() + ", " +
162 srcValues
[index
* 3 + 1].toString() + ", " +
163 srcValues
[index
* 3 + 2].toString() + "]";
165 returnValueAsString: function(value
) {
166 return value
=== null ? 'null' :
167 ("[" + value
[0] + ", " + value
[1] + ", " + value
[2] + "]");
169 checkType: function(value
) {
171 typeof value
.length
=== 'number' &&
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];
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],
185 jsTypeOf
: 'Float32Array',
186 setter
: 'uniform4fv',
189 invalidSet: function(loc
) {
190 gl
.uniform1fv(loc
, [2]);
192 illegalSet: function(loc
) {
193 gl
.uniform1fv(loc
, 2);
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() + "]";
201 returnValueAsString: function(value
) {
202 return value
=== null ? 'null' :
203 ("[" + value
[0] + ", " + value
[1] +
204 ", " + value
[2] + ", " + value
[3] + "]");
206 checkType: function(value
) {
208 typeof value
.length
=== 'number' &&
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];
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],
224 for (var tt
= 0; tt
< typeInfos
.length
; ++tt
) {
225 var typeInfo
= typeInfos
[tt
];
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
);
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 section 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
;
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");
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." + typeInfo
.setter
);
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.getUniform");
273 assertMsg(typeInfo
.checkValue(typeInfo
, ii
, value
),
274 "value put in (" + typeInfo
.srcValueAsString(ii
, srcValues
) +
275 ") matches value pulled out (" +
276 typeInfo
.returnValueAsString(value
) + ")");
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
) {
284 typeInfo
.illegalSet(loc
);
286 exceptionCaught
= true;
288 assertMsg(exceptionCaught
, "passing non-array to glUniform*fv should throw TypeError");
292 glErrorShouldBe(gl
, gl
.NO_ERROR
,
293 "can call gl.useProgram(null)");