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