OLD | NEW |
| (Empty) |
1 <!-- | |
2 Copyright (c) 2011 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> | |
7 <html> | |
8 <head> | |
9 <meta charset="utf-8"> | |
10 <title>WebGL OES_vertex_array_object Conformance Tests</title> | |
11 <link rel="stylesheet" href="../resources/js-test-style.css"/> | |
12 <script src="../resources/desktop-gl-constants.js" type="text/javascript"></scri
pt> | |
13 <script src="../resources/js-test-pre.js"></script> | |
14 <script src="resources/webgl-test.js"></script> | |
15 <script src="resources/webgl-test-utils.js"></script> | |
16 </head> | |
17 <body> | |
18 <div id="description"></div> | |
19 <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> | |
20 <div id="console"></div> | |
21 <!-- Shaders for testing standard derivatives --> | |
22 | |
23 <script> | |
24 description("This test verifies the functionality of the OES_vertex_array_object
extension, if it is available."); | |
25 | |
26 debug(""); | |
27 | |
28 var wtu = WebGLTestUtils; | |
29 var canvas = document.getElementById("canvas"); | |
30 var gl = create3DContext(canvas); | |
31 var ext = null; | |
32 var vao = null; | |
33 | |
34 if (!gl) { | |
35 testFailed("WebGL context does not exist"); | |
36 } else { | |
37 testPassed("WebGL context exists"); | |
38 | |
39 // Run tests with extension disabled | |
40 runBindingTestDisabled(); | |
41 | |
42 // Query the extension and store globally so shouldBe can access it | |
43 ext = gl.getExtension("OES_vertex_array_object"); | |
44 if (!ext) { | |
45 testPassed("No OES_vertex_array_object support -- this is legal"); | |
46 | |
47 runSupportedTest(false); | |
48 } else { | |
49 testPassed("Successfully enabled OES_vertex_array_object extension"); | |
50 | |
51 runSupportedTest(true); | |
52 runBindingTestEnabled(); | |
53 runObjectTest(); | |
54 runAttributeTests(); | |
55 runAttributeValueTests(); | |
56 runDrawTests(); | |
57 } | |
58 } | |
59 | |
60 function runSupportedTest(extensionEnabled) { | |
61 var supported = gl.getSupportedExtensions(); | |
62 if (supported.indexOf("OES_vertex_array_object") >= 0) { | |
63 if (extensionEnabled) { | |
64 testPassed("OES_vertex_array_object listed as supported and getExten
sion succeeded"); | |
65 } else { | |
66 testFailed("OES_vertex_array_object listed as supported but getExten
sion failed"); | |
67 } | |
68 } else { | |
69 if (extensionEnabled) { | |
70 testFailed("OES_vertex_array_object not listed as supported but getE
xtension succeeded"); | |
71 } else { | |
72 testPassed("OES_vertex_array_object not listed as supported and getE
xtension failed -- this is legal"); | |
73 } | |
74 } | |
75 } | |
76 | |
77 function runBindingTestDisabled() { | |
78 debug("Testing binding enum with extension disabled"); | |
79 | |
80 // Use the constant directly as we don't have the extension | |
81 var VERTEX_ARRAY_BINDING_OES = 0x85B5; | |
82 | |
83 gl.getParameter(VERTEX_ARRAY_BINDING_OES); | |
84 glErrorShouldBe(gl, gl.INVALID_ENUM, "VERTEX_ARRAY_BINDING_OES should not be
queryable if extension is disabled"); | |
85 } | |
86 | |
87 function runBindingTestEnabled() { | |
88 debug("Testing binding enum with extension enabled"); | |
89 | |
90 shouldBe("ext.VERTEX_ARRAY_BINDING_OES", "0x85B5"); | |
91 | |
92 gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES); | |
93 glErrorShouldBe(gl, gl.NO_ERROR, "VERTEX_ARRAY_BINDING_OES query should succ
eed if extension is enable"); | |
94 | |
95 // Default value is null | |
96 if (gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) === null) { | |
97 testPassed("Default value of VERTEX_ARRAY_BINDING_OES is null"); | |
98 } else { | |
99 testFailed("Default value of VERTEX_ARRAY_BINDING_OES is not null"); | |
100 } | |
101 | |
102 debug("Testing binding a VAO"); | |
103 var vao0 = ext.createVertexArrayOES(); | |
104 var vao1 = ext.createVertexArrayOES(); | |
105 shouldBeNull("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES)"); | |
106 ext.bindVertexArrayOES(vao0); | |
107 if (gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) == vao0) { | |
108 testPassed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is expected VA
O"); | |
109 } else { | |
110 testFailed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is not expecte
d VAO") | |
111 } | |
112 ext.bindVertexArrayOES(vao1); | |
113 if (gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) == vao1) { | |
114 testPassed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is expected VA
O"); | |
115 } else { | |
116 testFailed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is not expecte
d VAO") | |
117 } | |
118 ext.bindVertexArrayOES(null); | |
119 shouldBeNull("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES)"); | |
120 ext.deleteVertexArrayOES(vao0); | |
121 ext.deleteVertexArrayOES(vao1); | |
122 } | |
123 | |
124 function runObjectTest() { | |
125 debug("Testing object creation"); | |
126 | |
127 vao = ext.createVertexArrayOES(); | |
128 glErrorShouldBe(gl, gl.NO_ERROR, "createVertexArrayOES should not set an err
or"); | |
129 shouldBeNonNull("vao"); | |
130 | |
131 // Expect false if never bound | |
132 shouldBeFalse("ext.isVertexArrayOES(vao)"); | |
133 ext.bindVertexArrayOES(vao); | |
134 shouldBeTrue("ext.isVertexArrayOES(vao)"); | |
135 ext.bindVertexArrayOES(null); | |
136 shouldBeTrue("ext.isVertexArrayOES(vao)"); | |
137 | |
138 shouldBeFalse("ext.isVertexArrayOES()"); | |
139 shouldBeFalse("ext.isVertexArrayOES(null)"); | |
140 | |
141 ext.deleteVertexArrayOES(vao); | |
142 vao = null; | |
143 } | |
144 | |
145 function runAttributeTests() { | |
146 debug("Testing attributes work across bindings"); | |
147 | |
148 var states = []; | |
149 | |
150 var attrCount = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); | |
151 for (var n = 0; n < attrCount; n++) { | |
152 gl.bindBuffer(gl.ARRAY_BUFFER, null); | |
153 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); | |
154 | |
155 var state = {}; | |
156 states.push(state); | |
157 | |
158 var vao = state.vao = ext.createVertexArrayOES(); | |
159 ext.bindVertexArrayOES(vao); | |
160 | |
161 if (n % 2 == 0) { | |
162 gl.enableVertexAttribArray(n); | |
163 } else { | |
164 gl.disableVertexAttribArray(n); | |
165 } | |
166 | |
167 if (n % 2 == 0) { | |
168 var buffer = state.buffer = gl.createBuffer(); | |
169 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | |
170 gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.STATIC_DRAW); | |
171 | |
172 gl.vertexAttribPointer(n, 1 + n % 4, gl.FLOAT, true, n * 4, n * 4); | |
173 } | |
174 | |
175 if (n % 2 == 0) { | |
176 var elbuffer = state.elbuffer = gl.createBuffer(); | |
177 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elbuffer); | |
178 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 1024, gl.STATIC_DRAW); | |
179 } | |
180 | |
181 ext.bindVertexArrayOES(null); | |
182 } | |
183 | |
184 var anyMismatch = false; | |
185 for (var n = 0; n < attrCount; n++) { | |
186 var state = states[n]; | |
187 | |
188 ext.bindVertexArrayOES(state.vao); | |
189 | |
190 var isEnabled = gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_ENABLED); | |
191 if ((n % 2 == 1) || isEnabled) { | |
192 // Valid | |
193 } else { | |
194 testFailed("VERTEX_ATTRIB_ARRAY_ENABLED not preserved"); | |
195 anyMismatch = true; | |
196 } | |
197 | |
198 var buffer = gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
); | |
199 if (n % 2 == 0) { | |
200 if (buffer == state.buffer) { | |
201 // Matched | |
202 if ((gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_SIZE) == 1 + n
% 4) && | |
203 (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_TYPE) == gl.FL
OAT) && | |
204 (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED) ==
true) && | |
205 (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_STRIDE) == n *
4) && | |
206 (gl.getVertexAttribOffset(n, gl.VERTEX_ATTRIB_ARRAY_POINTER)
== n * 4)) { | |
207 // Matched | |
208 } else { | |
209 testFailed("VERTEX_ATTRIB_ARRAY_* not preserved"); | |
210 anyMismatch = true; | |
211 } | |
212 } else { | |
213 testFailed("VERTEX_ATTRIB_ARRAY_BUFFER_BINDING not preserved"); | |
214 anyMismatch = true; | |
215 } | |
216 } else { | |
217 // GL_CURRENT_VERTEX_ATTRIB is not preserved | |
218 if (buffer) { | |
219 testFailed("VERTEX_ATTRIB_ARRAY_BUFFER_BINDING not preserved"); | |
220 anyMismatch = true; | |
221 } | |
222 } | |
223 | |
224 var elbuffer = gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING); | |
225 if (n % 2 == 0) { | |
226 if (elbuffer == state.elbuffer) { | |
227 // Matched | |
228 } else { | |
229 testFailed("ELEMENT_ARRAY_BUFFER_BINDING not preserved"); | |
230 anyMismatch = true; | |
231 } | |
232 } else { | |
233 if (elbuffer == null) { | |
234 // Matched | |
235 } else { | |
236 testFailed("ELEMENT_ARRAY_BUFFER_BINDING not preserved"); | |
237 anyMismatch = true; | |
238 } | |
239 } | |
240 } | |
241 ext.bindVertexArrayOES(null); | |
242 if (!anyMismatch) { | |
243 testPassed("All attributes preserved across bindings"); | |
244 } | |
245 | |
246 for (var n = 0; n < attrCount; n++) { | |
247 var state = states[n]; | |
248 ext.deleteVertexArrayOES(state.vao); | |
249 } | |
250 } | |
251 | |
252 function runAttributeValueTests() { | |
253 debug("Testing that attribute values are not attached to bindings"); | |
254 | |
255 var v; | |
256 var vao0 = ext.createVertexArrayOES(); | |
257 var anyFailed = false; | |
258 | |
259 ext.bindVertexArrayOES(null); | |
260 gl.vertexAttrib4f(0, 0, 1, 2, 3); | |
261 | |
262 v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB); | |
263 if (!(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)) { | |
264 testFailed("Vertex attrib value not round-tripped?"); | |
265 anyFailed = true; | |
266 } | |
267 | |
268 ext.bindVertexArrayOES(vao0); | |
269 | |
270 v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB); | |
271 if (!(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)) { | |
272 testFailed("Vertex attrib value reset across bindings"); | |
273 anyFailed = true; | |
274 } | |
275 | |
276 gl.vertexAttrib4f(0, 4, 5, 6, 7); | |
277 ext.bindVertexArrayOES(null); | |
278 | |
279 v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB); | |
280 if (!(v[0] == 4 && v[1] == 5 && v[2] == 6 && v[3] == 7)) { | |
281 testFailed("Vertex attrib value bound to buffer"); | |
282 anyFailed = true; | |
283 } | |
284 | |
285 if (!anyFailed) { | |
286 testPassed("Vertex attribute values are not attached to bindings") | |
287 } | |
288 | |
289 ext.bindVertexArrayOES(null); | |
290 ext.deleteVertexArrayOES(vao0); | |
291 } | |
292 | |
293 function runDrawTests() { | |
294 debug("Testing draws with various VAO bindings"); | |
295 | |
296 canvas.width = 50; canvas.height = 50; | |
297 gl.viewport(0, 0, canvas.width, canvas.height); | |
298 | |
299 var vao0 = ext.createVertexArrayOES(); | |
300 var vao1 = ext.createVertexArrayOES(); | |
301 | |
302 var program = wtu.setupSimpleTextureProgram(gl, 0, 1); | |
303 | |
304 function setupQuad(s) { | |
305 var opt_positionLocation = 0; | |
306 var opt_texcoordLocation = 1; | |
307 var vertexObject = gl.createBuffer(); | |
308 gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); | |
309 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ | |
310 1.0 * s, 1.0 * s, 0.0, | |
311 -1.0 * s, 1.0 * s, 0.0, | |
312 -1.0 * s, -1.0 * s, 0.0, | |
313 1.0 * s, 1.0 * s, 0.0, | |
314 -1.0 * s, -1.0 * s, 0.0, | |
315 1.0 * s, -1.0 * s, 0.0]), gl.STATIC_DRAW); | |
316 gl.enableVertexAttribArray(opt_positionLocation); | |
317 gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0); | |
318 | |
319 var vertexObject = gl.createBuffer(); | |
320 gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); | |
321 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ | |
322 1.0 * s, 1.0 * s, | |
323 0.0 * s, 1.0 * s, | |
324 0.0 * s, 0.0 * s, | |
325 1.0 * s, 1.0 * s, | |
326 0.0 * s, 0.0 * s, | |
327 1.0 * s, 0.0 * s]), gl.STATIC_DRAW); | |
328 gl.enableVertexAttribArray(opt_texcoordLocation); | |
329 gl.vertexAttribPointer(opt_texcoordLocation, 2, gl.FLOAT, false, 0, 0); | |
330 }; | |
331 | |
332 function readLocation(x, y) { | |
333 var pixels = new Uint8Array(1 * 1 * 4); | |
334 gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels); | |
335 return pixels; | |
336 }; | |
337 function testPixel(blackList, whiteList) { | |
338 function testList(list, expected) { | |
339 for (var n = 0; n < list.length; n++) { | |
340 var l = list[n]; | |
341 var x = -Math.floor(l * canvas.width / 2) + canvas.width / 2; | |
342 var y = -Math.floor(l * canvas.height / 2) + canvas.height / 2; | |
343 var source = readLocation(x, y); | |
344 if (Math.abs(source[0] - expected) > 2) { | |
345 return false; | |
346 } | |
347 } | |
348 return true; | |
349 } | |
350 return testList(blackList, 0) && testList(whiteList, 255); | |
351 }; | |
352 function verifyDraw(drawNumber, s) { | |
353 wtu.drawQuad(gl); | |
354 var blackList = []; | |
355 var whiteList = []; | |
356 var points = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0]; | |
357 for (var n = 0; n < points.length; n++) { | |
358 if (points[n] <= s) { | |
359 blackList.push(points[n]); | |
360 } else { | |
361 whiteList.push(points[n]); | |
362 } | |
363 } | |
364 if (testPixel(blackList, whiteList)) { | |
365 testPassed("Draw " + drawNumber + " passed pixel test"); | |
366 } else { | |
367 testFailed("Draw " + drawNumber + " failed pixel test"); | |
368 } | |
369 }; | |
370 | |
371 // Setup all bindings | |
372 setupQuad(1); | |
373 ext.bindVertexArrayOES(vao0); | |
374 setupQuad(0.5); | |
375 ext.bindVertexArrayOES(vao1); | |
376 setupQuad(0.25); | |
377 | |
378 // Verify drawing | |
379 ext.bindVertexArrayOES(null); | |
380 verifyDraw(0, 1); | |
381 ext.bindVertexArrayOES(vao0); | |
382 verifyDraw(1, 0.5); | |
383 ext.bindVertexArrayOES(vao1); | |
384 verifyDraw(2, 0.25); | |
385 | |
386 ext.bindVertexArrayOES(null); | |
387 ext.deleteVertexArrayOES(vao0); | |
388 ext.deleteVertexArrayOES(vao1); | |
389 } | |
390 | |
391 debug(""); | |
392 successfullyParsed = true; | |
393 </script> | |
394 <script src="../resources/js-test-post.js"></script> | |
395 | |
396 </body> | |
397 </html> | |
OLD | NEW |