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