Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(477)

Side by Side Diff: conformance/more/util.js

Issue 8342021: Add webgl conformance tests r15841. (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/webgl/sdk/tests/
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « conformance/more/unit.js ('k') | conformance/programs/00_test_list.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 Utilities for the OpenGL ES 2.0 HTML Canvas context
3
4 Copyright (C) 2011 Ilmari Heikkinen <ilmari.heikkinen@gmail.com>
5
6 Permission is hereby granted, free of charge, to any person
7 obtaining a copy of this software and associated documentation
8 files (the "Software"), to deal in the Software without
9 restriction, including without limitation the rights to use,
10 copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the
12 Software is furnished to do so, subject to the following
13 conditions:
14
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28 function loadTexture(gl, elem, mipmaps) {
29 var tex = gl.createTexture();
30 gl.bindTexture(gl.TEXTURE_2D, tex);
31 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, elem);
32 if (mipmaps != false)
33 gl.generateMipmap(gl.TEXTURE_2D);
34 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
35 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
36 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
37 if (mipmaps)
38 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINE AR);
39 else
40 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
41 return tex;
42 }
43
44 function getShader(gl, id) {
45 var shaderScript = document.getElementById(id);
46 if (!shaderScript) {
47 throw(new Error("No shader element with id: "+id));
48 }
49
50 var str = "";
51 var k = shaderScript.firstChild;
52 while (k) {
53 if (k.nodeType == 3)
54 str += k.textContent;
55 k = k.nextSibling;
56 }
57
58 var shader;
59 if (shaderScript.type == "x-shader/x-fragment") {
60 shader = gl.createShader(gl.FRAGMENT_SHADER);
61 } else if (shaderScript.type == "x-shader/x-vertex") {
62 shader = gl.createShader(gl.VERTEX_SHADER);
63 } else {
64 throw(new Error("Unknown shader type "+shaderScript.type));
65 }
66
67 gl.shaderSource(shader, str);
68 gl.compileShader(shader);
69
70 if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) != 1) {
71 var ilog = gl.getShaderInfoLog(shader);
72 gl.deleteShader(shader);
73 throw(new Error("Failed to compile shader "+shaderScript.id + ", Shader info log: " + ilog));
74 }
75 return shader;
76 }
77
78 function loadShaderArray(gl, shaders) {
79 var id = gl.createProgram();
80 var shaderObjs = [];
81 for (var i=0; i<shaders.length; ++i) {
82 try {
83 var sh = getShader(gl, shaders[i]);
84 shaderObjs.push(sh);
85 gl.attachShader(id, sh);
86 } catch (e) {
87 var pr = {program: id, shaders: shaderObjs};
88 deleteShader(gl, pr);
89 throw (e);
90 }
91 }
92 var prog = {program: id, shaders: shaderObjs};
93 gl.linkProgram(id);
94 gl.validateProgram(id);
95 if (gl.getProgramParameter(id, gl.LINK_STATUS) != 1) {
96 deleteShader(gl,prog);
97 throw(new Error("Failed to link shader"));
98 }
99 if (gl.getProgramParameter(id, gl.VALIDATE_STATUS) != 1) {
100 deleteShader(gl,prog);
101 throw(new Error("Failed to validate shader"));
102 }
103 return prog;
104 }
105 function loadShader(gl) {
106 var sh = [];
107 for (var i=1; i<arguments.length; ++i)
108 sh.push(arguments[i]);
109 return loadShaderArray(gl, sh);
110 }
111
112 function deleteShader(gl, sh) {
113 gl.useProgram(null);
114 sh.shaders.forEach(function(s){
115 gl.detachShader(sh.program, s);
116 gl.deleteShader(s);
117 });
118 gl.deleteProgram(sh.program);
119 }
120
121 function getGLErrorAsString(ctx, err) {
122 if (err === ctx.NO_ERROR) {
123 return "NO_ERROR";
124 }
125 for (var name in ctx) {
126 if (ctx[name] === err) {
127 return name;
128 }
129 }
130 return err.toString();
131 }
132
133 function checkError(gl, msg) {
134 var e = gl.getError();
135 if (e != gl.NO_ERROR) {
136 log("Error " + getGLErrorAsString(gl, e) + " at " + msg);
137 }
138 return e;
139 }
140
141 function throwError(gl, msg) {
142 var e = gl.getError();
143 if (e != 0) {
144 throw(new Error("Error " + getGLErrorAsString(gl, e) + " at " + msg));
145 }
146 }
147
148 Math.cot = function(z) { return 1.0 / Math.tan(z); }
149
150 /*
151 Matrix utilities, using the OpenGL element order where
152 the last 4 elements are the translation column.
153
154 Uses flat arrays as matrices for performance.
155
156 Most operations have in-place variants to avoid allocating temporary matrices.
157
158 Naming logic:
159 Matrix.method operates on a 4x4 Matrix and returns a new Matrix.
160 Matrix.method3x3 operates on a 3x3 Matrix and returns a new Matrix. Not all operations have a 3x3 version (as 3x3 is usually only used for the normal matrix : Matrix.transpose3x3(Matrix.inverseTo3x3(mat4x4)))
161 Matrix.method[3x3]InPlace(args, target) stores its result in the target matr ix.
162
163 Matrix.scale([sx, sy, sz]) -- non-uniform scale by vector
164 Matrix.scale1(s) -- uniform scale by scalar
165 Matrix.scale3(sx, sy, sz) -- non-uniform scale by scalars
166
167 Ditto for translate.
168 */
169 Matrix = {
170 identity : [
171 1.0, 0.0, 0.0, 0.0,
172 0.0, 1.0, 0.0, 0.0,
173 0.0, 0.0, 1.0, 0.0,
174 0.0, 0.0, 0.0, 1.0
175 ],
176
177 newIdentity : function() {
178 return [
179 1.0, 0.0, 0.0, 0.0,
180 0.0, 1.0, 0.0, 0.0,
181 0.0, 0.0, 1.0, 0.0,
182 0.0, 0.0, 0.0, 1.0
183 ];
184 },
185
186 newIdentity3x3 : function() {
187 return [
188 1.0, 0.0, 0.0,
189 0.0, 1.0, 0.0,
190 0.0, 0.0, 1.0
191 ];
192 },
193
194 copyMatrix : function(src, dst) {
195 for (var i=0; i<16; i++) dst[i] = src[i];
196 return dst;
197 },
198
199 to3x3 : function(m) {
200 return [
201 m[0], m[1], m[2],
202 m[4], m[5], m[6],
203 m[8], m[9], m[10]
204 ];
205 },
206
207 // orthonormal matrix inverse
208 inverseON : function(m) {
209 var n = this.transpose4x4(m);
210 var t = [m[12], m[13], m[14]];
211 n[3] = n[7] = n[11] = 0;
212 n[12] = -Vec3.dot([n[0], n[4], n[8]], t);
213 n[13] = -Vec3.dot([n[1], n[5], n[9]], t);
214 n[14] = -Vec3.dot([n[2], n[6], n[10]], t);
215 return n;
216 },
217
218 inverseTo3x3 : function(m) {
219 return this.inverse4x4to3x3InPlace(m, this.newIdentity3x3());
220 },
221
222 inverseTo3x3InPlace : function(m,n) {
223 var a11 = m[10]*m[5]-m[6]*m[9],
224 a21 = -m[10]*m[1]+m[2]*m[9],
225 a31 = m[6]*m[1]-m[2]*m[5],
226 a12 = -m[10]*m[4]+m[6]*m[8],
227 a22 = m[10]*m[0]-m[2]*m[8],
228 a32 = -m[6]*m[0]+m[2]*m[4],
229 a13 = m[9]*m[4]-m[5]*m[8],
230 a23 = -m[9]*m[0]+m[1]*m[8],
231 a33 = m[5]*m[0]-m[1]*m[4];
232 var det = m[0]*(a11) + m[1]*(a12) + m[2]*(a13);
233 if (det == 0) // no inverse
234 return [1,0,0,0,1,0,0,0,1];
235 var idet = 1 / det;
236 n[0] = idet*a11;
237 n[1] = idet*a21;
238 n[2] = idet*a31;
239 n[3] = idet*a12;
240 n[4] = idet*a22;
241 n[5] = idet*a32;
242 n[6] = idet*a13;
243 n[7] = idet*a23;
244 n[8] = idet*a33;
245 return n;
246 },
247
248 inverse3x3 : function(m) {
249 return this.inverse3x3InPlace(m, this.newIdentity3x3());
250 },
251
252 inverse3x3InPlace : function(m,n) {
253 var a11 = m[8]*m[4]-m[5]*m[7],
254 a21 = -m[8]*m[1]+m[2]*m[7],
255 a31 = m[5]*m[1]-m[2]*m[4],
256 a12 = -m[8]*m[3]+m[5]*m[6],
257 a22 = m[8]*m[0]-m[2]*m[6],
258 a32 = -m[5]*m[0]+m[2]*m[3],
259 a13 = m[7]*m[4]-m[4]*m[8],
260 a23 = -m[7]*m[0]+m[1]*m[6],
261 a33 = m[4]*m[0]-m[1]*m[3];
262 var det = m[0]*(a11) + m[1]*(a12) + m[2]*(a13);
263 if (det == 0) // no inverse
264 return [1,0,0,0,1,0,0,0,1];
265 var idet = 1 / det;
266 n[0] = idet*a11;
267 n[1] = idet*a21;
268 n[2] = idet*a31;
269 n[3] = idet*a12;
270 n[4] = idet*a22;
271 n[5] = idet*a32;
272 n[6] = idet*a13;
273 n[7] = idet*a23;
274 n[8] = idet*a33;
275 return n;
276 },
277
278 frustum : function (left, right, bottom, top, znear, zfar) {
279 var X = 2*znear/(right-left);
280 var Y = 2*znear/(top-bottom);
281 var A = (right+left)/(right-left);
282 var B = (top+bottom)/(top-bottom);
283 var C = -(zfar+znear)/(zfar-znear);
284 var D = -2*zfar*znear/(zfar-znear);
285
286 return [
287 X, 0, 0, 0,
288 0, Y, 0, 0,
289 A, B, C, -1,
290 0, 0, D, 0
291 ];
292 },
293
294 perspective : function (fovy, aspect, znear, zfar) {
295 var ymax = znear * Math.tan(fovy * Math.PI / 360.0);
296 var ymin = -ymax;
297 var xmin = ymin * aspect;
298 var xmax = ymax * aspect;
299
300 return this.frustum(xmin, xmax, ymin, ymax, znear, zfar);
301 },
302
303 mul4x4 : function (a,b) {
304 return this.mul4x4InPlace(a,b,this.newIdentity());
305 },
306
307 mul4x4InPlace : function (a, b, c) {
308 c[0] = b[0] * a[0] +
309 b[0+1] * a[4] +
310 b[0+2] * a[8] +
311 b[0+3] * a[12];
312 c[0+1] = b[0] * a[1] +
313 b[0+1] * a[5] +
314 b[0+2] * a[9] +
315 b[0+3] * a[13];
316 c[0+2] = b[0] * a[2] +
317 b[0+1] * a[6] +
318 b[0+2] * a[10] +
319 b[0+3] * a[14];
320 c[0+3] = b[0] * a[3] +
321 b[0+1] * a[7] +
322 b[0+2] * a[11] +
323 b[0+3] * a[15];
324 c[4] = b[4] * a[0] +
325 b[4+1] * a[4] +
326 b[4+2] * a[8] +
327 b[4+3] * a[12];
328 c[4+1] = b[4] * a[1] +
329 b[4+1] * a[5] +
330 b[4+2] * a[9] +
331 b[4+3] * a[13];
332 c[4+2] = b[4] * a[2] +
333 b[4+1] * a[6] +
334 b[4+2] * a[10] +
335 b[4+3] * a[14];
336 c[4+3] = b[4] * a[3] +
337 b[4+1] * a[7] +
338 b[4+2] * a[11] +
339 b[4+3] * a[15];
340 c[8] = b[8] * a[0] +
341 b[8+1] * a[4] +
342 b[8+2] * a[8] +
343 b[8+3] * a[12];
344 c[8+1] = b[8] * a[1] +
345 b[8+1] * a[5] +
346 b[8+2] * a[9] +
347 b[8+3] * a[13];
348 c[8+2] = b[8] * a[2] +
349 b[8+1] * a[6] +
350 b[8+2] * a[10] +
351 b[8+3] * a[14];
352 c[8+3] = b[8] * a[3] +
353 b[8+1] * a[7] +
354 b[8+2] * a[11] +
355 b[8+3] * a[15];
356 c[12] = b[12] * a[0] +
357 b[12+1] * a[4] +
358 b[12+2] * a[8] +
359 b[12+3] * a[12];
360 c[12+1] = b[12] * a[1] +
361 b[12+1] * a[5] +
362 b[12+2] * a[9] +
363 b[12+3] * a[13];
364 c[12+2] = b[12] * a[2] +
365 b[12+1] * a[6] +
366 b[12+2] * a[10] +
367 b[12+3] * a[14];
368 c[12+3] = b[12] * a[3] +
369 b[12+1] * a[7] +
370 b[12+2] * a[11] +
371 b[12+3] * a[15];
372 return c;
373 },
374
375 mulv4 : function (a, v) {
376 c = new Array(4);
377 for (var i=0; i<4; ++i) {
378 var x = 0;
379 for (var k=0; k<4; ++k)
380 x += v[k] * a[k*4+i];
381 c[i] = x;
382 }
383 return c;
384 },
385
386 rotate : function (angle, axis) {
387 axis = Vec3.normalize(axis);
388 var x=axis[0], y=axis[1], z=axis[2];
389 var c = Math.cos(angle);
390 var c1 = 1-c;
391 var s = Math.sin(angle);
392 return [
393 x*x*c1+c, y*x*c1+z*s, z*x*c1-y*s, 0,
394 x*y*c1-z*s, y*y*c1+c, y*z*c1+x*s, 0,
395 x*z*c1+y*s, y*z*c1-x*s, z*z*c1+c, 0,
396 0,0,0,1
397 ];
398 },
399 rotateInPlace : function(angle, axis, m) {
400 axis = Vec3.normalize(axis);
401 var x=axis[0], y=axis[1], z=axis[2];
402 var c = Math.cos(angle);
403 var c1 = 1-c;
404 var s = Math.sin(angle);
405 var tmpMatrix = this.tmpMatrix;
406 var tmpMatrix2 = this.tmpMatrix2;
407 tmpMatrix[0] = x*x*c1+c; tmpMatrix[1] = y*x*c1+z*s; tmpMatrix[2] = z*x*c1-y* s; tmpMatrix[3] = 0;
408 tmpMatrix[4] = x*y*c1-z*s; tmpMatrix[5] = y*y*c1+c; tmpMatrix[6] = y*z*c1+x* s; tmpMatrix[7] = 0;
409 tmpMatrix[8] = x*z*c1+y*s; tmpMatrix[9] = y*z*c1-x*s; tmpMatrix[10] = z*z*c1 +c; tmpMatrix[11] = 0;
410 tmpMatrix[12] = 0; tmpMatrix[13] = 0; tmpMatrix[14] = 0; tmpMatrix[15] = 1;
411 this.copyMatrix(m, tmpMatrix2);
412 return this.mul4x4InPlace(tmpMatrix2, tmpMatrix, m);
413 },
414
415 scale : function(v) {
416 return [
417 v[0], 0, 0, 0,
418 0, v[1], 0, 0,
419 0, 0, v[2], 0,
420 0, 0, 0, 1
421 ];
422 },
423 scale3 : function(x,y,z) {
424 return [
425 x, 0, 0, 0,
426 0, y, 0, 0,
427 0, 0, z, 0,
428 0, 0, 0, 1
429 ];
430 },
431 scale1 : function(s) {
432 return [
433 s, 0, 0, 0,
434 0, s, 0, 0,
435 0, 0, s, 0,
436 0, 0, 0, 1
437 ];
438 },
439 scale3InPlace : function(x, y, z, m) {
440 var tmpMatrix = this.tmpMatrix;
441 var tmpMatrix2 = this.tmpMatrix2;
442 tmpMatrix[0] = x; tmpMatrix[1] = 0; tmpMatrix[2] = 0; tmpMatrix[3] = 0;
443 tmpMatrix[4] = 0; tmpMatrix[5] = y; tmpMatrix[6] = 0; tmpMatrix[7] = 0;
444 tmpMatrix[8] = 0; tmpMatrix[9] = 0; tmpMatrix[10] = z; tmpMatrix[11] = 0;
445 tmpMatrix[12] = 0; tmpMatrix[13] = 0; tmpMatrix[14] = 0; tmpMatrix[15] = 1;
446 this.copyMatrix(m, tmpMatrix2);
447 return this.mul4x4InPlace(tmpMatrix2, tmpMatrix, m);
448 },
449 scale1InPlace : function(s, m) { return this.scale3InPlace(s, s, s, m); },
450 scaleInPlace : function(s, m) { return this.scale3InPlace(s[0],s[1],s[2],m); } ,
451
452 translate3 : function(x,y,z) {
453 return [
454 1, 0, 0, 0,
455 0, 1, 0, 0,
456 0, 0, 1, 0,
457 x, y, z, 1
458 ];
459 },
460
461 translate : function(v) {
462 return this.translate3(v[0], v[1], v[2]);
463 },
464 tmpMatrix : [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0],
465 tmpMatrix2 : [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0],
466 translate3InPlace : function(x,y,z,m) {
467 var tmpMatrix = this.tmpMatrix;
468 var tmpMatrix2 = this.tmpMatrix2;
469 tmpMatrix[0] = 1; tmpMatrix[1] = 0; tmpMatrix[2] = 0; tmpMatrix[3] = 0;
470 tmpMatrix[4] = 0; tmpMatrix[5] = 1; tmpMatrix[6] = 0; tmpMatrix[7] = 0;
471 tmpMatrix[8] = 0; tmpMatrix[9] = 0; tmpMatrix[10] = 1; tmpMatrix[11] = 0;
472 tmpMatrix[12] = x; tmpMatrix[13] = y; tmpMatrix[14] = z; tmpMatrix[15] = 1;
473 this.copyMatrix(m, tmpMatrix2);
474 return this.mul4x4InPlace(tmpMatrix2, tmpMatrix, m);
475 },
476 translateInPlace : function(v,m){ return this.translate3InPlace(v[0], v[1], v[ 2], m); },
477
478 lookAt : function (eye, center, up) {
479 var z = Vec3.direction(eye, center);
480 var x = Vec3.normalizeInPlace(Vec3.cross(up, z));
481 var y = Vec3.normalizeInPlace(Vec3.cross(z, x));
482
483 var m = [
484 x[0], y[0], z[0], 0,
485 x[1], y[1], z[1], 0,
486 x[2], y[2], z[2], 0,
487 0, 0, 0, 1
488 ];
489
490 var t = [
491 1, 0, 0, 0,
492 0, 1, 0, 0,
493 0, 0, 1, 0,
494 -eye[0], -eye[1], -eye[2], 1
495 ];
496
497 return this.mul4x4(m,t);
498 },
499
500 transpose4x4 : function(m) {
501 return [
502 m[0], m[4], m[8], m[12],
503 m[1], m[5], m[9], m[13],
504 m[2], m[6], m[10], m[14],
505 m[3], m[7], m[11], m[15]
506 ];
507 },
508
509 transpose4x4InPlace : function(m) {
510 var tmp = 0.0;
511 tmp = m[1]; m[1] = m[4]; m[4] = tmp;
512 tmp = m[2]; m[2] = m[8]; m[8] = tmp;
513 tmp = m[3]; m[3] = m[12]; m[12] = tmp;
514 tmp = m[6]; m[6] = m[9]; m[9] = tmp;
515 tmp = m[7]; m[7] = m[13]; m[13] = tmp;
516 tmp = m[11]; m[11] = m[14]; m[14] = tmp;
517 return m;
518 },
519
520 transpose3x3 : function(m) {
521 return [
522 m[0], m[3], m[6],
523 m[1], m[4], m[7],
524 m[2], m[5], m[8]
525 ];
526 },
527
528 transpose3x3InPlace : function(m) {
529 var tmp = 0.0;
530 tmp = m[1]; m[1] = m[3]; m[3] = tmp;
531 tmp = m[2]; m[2] = m[6]; m[6] = tmp;
532 tmp = m[5]; m[5] = m[7]; m[7] = tmp;
533 return m;
534 },
535 }
536
537 Vec3 = {
538 make : function() { return [0,0,0]; },
539 copy : function(v) { return [v[0],v[1],v[2]]; },
540
541 add : function (u,v) {
542 return [u[0]+v[0], u[1]+v[1], u[2]+v[2]];
543 },
544
545 sub : function (u,v) {
546 return [u[0]-v[0], u[1]-v[1], u[2]-v[2]];
547 },
548
549 negate : function (u) {
550 return [-u[0], -u[1], -u[2]];
551 },
552
553 direction : function (u,v) {
554 return this.normalizeInPlace(this.sub(u,v));
555 },
556
557 normalizeInPlace : function(v) {
558 var imag = 1.0 / Math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
559 v[0] *= imag; v[1] *= imag; v[2] *= imag;
560 return v;
561 },
562
563 normalize : function(v) {
564 return this.normalizeInPlace(this.copy(v));
565 },
566
567 scale : function(f, v) {
568 return [f*v[0], f*v[1], f*v[2]];
569 },
570
571 dot : function(u,v) {
572 return u[0]*v[0] + u[1]*v[1] + u[2]*v[2];
573 },
574
575 inner : function(u,v) {
576 return [u[0]*v[0], u[1]*v[1], u[2]*v[2]];
577 },
578
579 cross : function(u,v) {
580 return [
581 u[1]*v[2] - u[2]*v[1],
582 u[2]*v[0] - u[0]*v[2],
583 u[0]*v[1] - u[1]*v[0]
584 ];
585 }
586 }
587
588 Shader = function(gl){
589 this.gl = gl;
590 this.shaders = [];
591 this.uniformLocations = {};
592 this.attribLocations = {};
593 for (var i=1; i<arguments.length; i++) {
594 this.shaders.push(arguments[i]);
595 }
596 }
597 Shader.prototype = {
598 id : null,
599 gl : null,
600 compiled : false,
601 shader : null,
602 shaders : [],
603
604 destroy : function() {
605 if (this.shader != null) deleteShader(this.gl, this.shader);
606 },
607
608 compile : function() {
609 this.shader = loadShaderArray(this.gl, this.shaders);
610 },
611
612 use : function() {
613 if (this.shader == null)
614 this.compile();
615 this.gl.useProgram(this.shader.program);
616 },
617
618 uniform1fv : function(name, value) {
619 var loc = this.uniform(name);
620 this.gl.uniform1fv(loc, value);
621 },
622
623 uniform2fv : function(name, value) {
624 var loc = this.uniform(name);
625 this.gl.uniform2fv(loc, value);
626 },
627
628 uniform3fv : function(name, value) {
629 var loc = this.uniform(name);
630 this.gl.uniform3fv(loc, value);
631 },
632
633 uniform4fv : function(name, value) {
634 var loc = this.uniform(name);
635 this.gl.uniform4fv(loc, value);
636 },
637
638 uniform1f : function(name, value) {
639 var loc = this.uniform(name);
640 this.gl.uniform1f(loc, value);
641 },
642
643 uniform2f : function(name, v1,v2) {
644 var loc = this.uniform(name);
645 this.gl.uniform2f(loc, v1,v2);
646 },
647
648 uniform3f : function(name, v1,v2,v3) {
649 var loc = this.uniform(name);
650 this.gl.uniform3f(loc, v1,v2,v3);
651 },
652
653 uniform4f : function(name, v1,v2,v3,v4) {
654 var loc = this.uniform(name);
655 this.gl.uniform4f(loc, v1, v2, v3, v4);
656 },
657
658 uniform1iv : function(name, value) {
659 var loc = this.uniform(name);
660 this.gl.uniform1iv(loc, value);
661 },
662
663 uniform2iv : function(name, value) {
664 var loc = this.uniform(name);
665 this.gl.uniform2iv(loc, value);
666 },
667
668 uniform3iv : function(name, value) {
669 var loc = this.uniform(name);
670 this.gl.uniform3iv(loc, value);
671 },
672
673 uniform4iv : function(name, value) {
674 var loc = this.uniform(name);
675 this.gl.uniform4iv(loc, value);
676 },
677
678 uniform1i : function(name, value) {
679 var loc = this.uniform(name);
680 this.gl.uniform1i(loc, value);
681 },
682
683 uniform2i : function(name, v1,v2) {
684 var loc = this.uniform(name);
685 this.gl.uniform2i(loc, v1,v2);
686 },
687
688 uniform3i : function(name, v1,v2,v3) {
689 var loc = this.uniform(name);
690 this.gl.uniform3i(loc, v1,v2,v3);
691 },
692
693 uniform4i : function(name, v1,v2,v3,v4) {
694 var loc = this.uniform(name);
695 this.gl.uniform4i(loc, v1, v2, v3, v4);
696 },
697
698 uniformMatrix4fv : function(name, value) {
699 var loc = this.uniform(name);
700 this.gl.uniformMatrix4fv(loc, false, value);
701 },
702
703 uniformMatrix3fv : function(name, value) {
704 var loc = this.uniform(name);
705 this.gl.uniformMatrix3fv(loc, false, value);
706 },
707
708 uniformMatrix2fv : function(name, value) {
709 var loc = this.uniform(name);
710 this.gl.uniformMatrix2fv(loc, false, value);
711 },
712
713 attrib : function(name) {
714 if (this.attribLocations[name] == null) {
715 var loc = this.gl.getAttribLocation(this.shader.program, name);
716 this.attribLocations[name] = loc;
717 }
718 return this.attribLocations[name];
719 },
720
721 uniform : function(name) {
722 if (this.uniformLocations[name] == null) {
723 var loc = this.gl.getUniformLocation(this.shader.program, name);
724 this.uniformLocations[name] = loc;
725 }
726 return this.uniformLocations[name];
727 }
728 }
729 Filter = function(gl, shader) {
730 Shader.apply(this, arguments);
731 }
732 Filter.prototype = new Shader();
733 Filter.prototype.apply = function(init) {
734 this.use();
735 var va = this.attrib("Vertex");
736 var ta = this.attrib("Tex");
737 var vbo = Quad.getCachedVBO(this.gl);
738 if (init) init(this);
739 vbo.draw(va, null, ta);
740 }
741
742
743 VBO = function(gl) {
744 this.gl = gl;
745 this.data = [];
746 this.elementsVBO = null;
747 for (var i=1; i<arguments.length; i++) {
748 if (arguments[i].elements)
749 this.elements = arguments[i];
750 else
751 this.data.push(arguments[i]);
752 }
753 }
754
755 VBO.prototype = {
756 initialized : false,
757 length : 0,
758 vbos : null,
759 type : 'TRIANGLES',
760 elementsVBO : null,
761 elements : null,
762
763 setData : function() {
764 this.destroy();
765 this.data = [];
766 for (var i=0; i<arguments.length; i++) {
767 if (arguments[i].elements)
768 this.elements = arguments[i];
769 else
770 this.data.push(arguments[i]);
771 }
772 },
773
774 destroy : function() {
775 if (this.vbos != null)
776 for (var i=0; i<this.vbos.length; i++)
777 this.gl.deleteBuffer(this.vbos[i]);
778 if (this.elementsVBO != null)
779 this.gl.deleteBuffer(this.elementsVBO);
780 this.length = this.elementsLength = 0;
781 this.vbos = this.elementsVBO = null;
782 this.initialized = false;
783 },
784
785 init : function() {
786 this.destroy();
787 var gl = this.gl;
788
789 gl.getError();
790 var vbos = [];
791 var length = 0;
792 for (var i=0; i<this.data.length; i++)
793 vbos.push(gl.createBuffer());
794 if (this.elements != null)
795 this.elementsVBO = gl.createBuffer();
796 try {
797 throwError(gl, "genBuffers");
798 for (var i = 0; i<this.data.length; i++) {
799 var d = this.data[i];
800 var dlen = Math.floor(d.data.length / d.size);
801 if (i == 0 || dlen < length)
802 length = dlen;
803 if (!d.floatArray)
804 d.floatArray = new Float32Array(d.data);
805 gl.bindBuffer(gl.ARRAY_BUFFER, vbos[i]);
806 throwError(gl, "bindBuffer");
807 gl.bufferData(gl.ARRAY_BUFFER, d.floatArray, gl.STATIC_DRAW);
808 throwError(gl, "bufferData");
809 }
810 if (this.elementsVBO != null) {
811 var d = this.elements;
812 this.elementsLength = d.data.length;
813 this.elementsType = d.type == gl.UNSIGNED_BYTE ? d.type : gl.UNSIGNED_SH ORT;
814 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.elementsVBO);
815 throwError(gl, "bindBuffer ELEMENT_ARRAY_BUFFER");
816 if (this.elementsType == gl.UNSIGNED_SHORT && !d.ushortArray) {
817 d.ushortArray = new Uint16Array(d.data);
818 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, d.ushortArray, gl.STATIC_DRAW);
819 } else if (this.elementsType == gl.UNSIGNED_BYTE && !d.ubyteArray) {
820 d.ubyteArray = new Uint8Array(d.data);
821 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, d.ubyteArray, gl.STATIC_DRAW);
822 }
823 throwError(gl, "bufferData ELEMENT_ARRAY_BUFFER");
824 }
825 } catch(e) {
826 for (var i=0; i<vbos.length; i++)
827 gl.deleteBuffer(vbos[i]);
828 throw(e);
829 }
830
831 gl.bindBuffer(gl.ARRAY_BUFFER, null);
832 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
833
834 this.length = length;
835 this.vbos = vbos;
836
837 this.initialized = true;
838 },
839
840 use : function() {
841 if (!this.initialized) this.init();
842 var gl = this.gl;
843 for (var i=0; i<arguments.length; i++) {
844 if (arguments[i] == null) continue;
845 gl.bindBuffer(gl.ARRAY_BUFFER, this.vbos[i]);
846 gl.vertexAttribPointer(arguments[i], this.data[i].size, gl.FLOAT, false, 0 , 0);
847 gl.enableVertexAttribArray(arguments[i]);
848 }
849 if (this.elementsVBO != null) {
850 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.elementsVBO);
851 }
852 },
853
854 draw : function() {
855 var args = [];
856 this.use.apply(this, arguments);
857 var gl = this.gl;
858 if (this.elementsVBO != null) {
859 gl.drawElements(gl[this.type], this.elementsLength, this.elementsType, 0);
860 } else {
861 gl.drawArrays(gl[this.type], 0, this.length);
862 }
863 }
864 }
865
866 FBO = function(gl, width, height, use_depth) {
867 this.gl = gl;
868 this.width = width;
869 this.height = height;
870 if (use_depth != null)
871 this.useDepth = use_depth;
872 }
873 FBO.prototype = {
874 initialized : false,
875 useDepth : true,
876 fbo : null,
877 rbo : null,
878 texture : null,
879
880 destroy : function() {
881 if (this.fbo) this.gl.deleteFramebuffer(this.fbo);
882 if (this.rbo) this.gl.deleteRenderbuffer(this.rbo);
883 if (this.texture) this.gl.deleteTexture(this.texture);
884 },
885
886 init : function() {
887 var gl = this.gl;
888 var w = this.width, h = this.height;
889 var fbo = this.fbo != null ? this.fbo : gl.createFramebuffer();
890 var rb;
891
892 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
893 checkError(gl, "FBO.init bindFramebuffer");
894 if (this.useDepth) {
895 rb = this.rbo != null ? this.rbo : gl.createRenderbuffer();
896 gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
897 checkError(gl, "FBO.init bindRenderbuffer");
898 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
899 checkError(gl, "FBO.init renderbufferStorage");
900 }
901
902 var tex = this.texture != null ? this.texture : gl.createTexture();
903 gl.bindTexture(gl.TEXTURE_2D, tex);
904 try {
905 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYT E, null);
906 } catch (e) { // argh, no null texture support
907 var tmp = this.getTempCanvas(w,h);
908 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tmp);
909 }
910 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
911 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
912 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
913 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
914 checkError(gl, "FBO.init tex");
915
916 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
917 checkError(gl, "FBO.init bind tex");
918
919 if (this.useDepth) {
920 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERB UFFER, rb);
921 checkError(gl, "FBO.init bind depth buffer");
922 }
923
924 var fbstat = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
925 if (fbstat != gl.FRAMEBUFFER_COMPLETE) {
926 var glv;
927 for (var v in gl) {
928 try { glv = gl[v]; } catch (e) { glv = null; }
929 if (glv == fbstat) { fbstat = v; break; }}
930 log("Framebuffer status: " + fbstat);
931 }
932 checkError(gl, "FBO.init check fbo");
933
934 this.fbo = fbo;
935 this.rbo = rb;
936 this.texture = tex;
937 this.initialized = true;
938 },
939
940 getTempCanvas : function(w, h) {
941 if (!FBO.tempCanvas) {
942 FBO.tempCanvas = document.createElement('canvas');
943 }
944 FBO.tempCanvas.width = w;
945 FBO.tempCanvas.height = h;
946 return FBO.tempCanvas;
947 },
948
949 use : function() {
950 if (!this.initialized) this.init();
951 this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.fbo);
952 }
953 }
954
955 function GLError(err, msg, fileName, lineNumber) {
956 this.message = msg;
957 this.glError = err;
958 }
959
960 GLError.prototype = new Error();
961
962 function makeGLErrorWrapper(gl, fname) {
963 return (function() {
964 try {
965 var rv = gl[fname].apply(gl, arguments);
966 var err = gl.getError();
967 if (err != gl.NO_ERROR) {
968 throw(new GLError(
969 err, "GL error "+getGLErrorAsString(gl, err)+" in "+fname));
970 }
971 return rv;
972 } catch (e) {
973 if (e.glError !== undefined) {
974 throw e;
975 }
976 throw(new Error("Threw " + e.name +
977 " in " + fname + "\n" +
978 e.message + "\n" +
979 arguments.callee.caller));
980 }
981 });
982 }
983
984 function wrapGLContext(gl) {
985 var wrap = {};
986 for (var i in gl) {
987 try {
988 if (typeof gl[i] == 'function') {
989 wrap[i] = makeGLErrorWrapper(gl, i);
990 } else {
991 wrap[i] = gl[i];
992 }
993 } catch (e) {
994 // log("wrapGLContext: Error accessing " + i);
995 }
996 }
997 wrap.getError = function(){ return gl.getError(); };
998 return wrap;
999 }
1000
1001 // Assert that f generates a specific GL error.
1002 function assertGLError(gl, err, name, f) {
1003 if (f == null) { f = name; name = null; }
1004 var r = false;
1005 var glErr = 0;
1006 try { f(); } catch(e) { r=true; glErr = e.glError; }
1007 if (glErr !== err) {
1008 if (glErr === undefined) {
1009 testFailed("assertGLError: UNEXPCETED EXCEPTION", name, f);
1010 } else {
1011 testFailed("assertGLError: expected: " + getGLErrorAsString(gl, err) +
1012 " actual: " + getGLErrorAsString(gl, glErr), name, f);
1013 }
1014 return false;
1015 }
1016 return true;
1017 }
1018
1019 // Assert that f generates some GL error. Used in situations where it's
1020 // ambigious which of multiple possible errors will be generated.
1021 function assertSomeGLError(gl, name, f) {
1022 if (f == null) { f = name; name = null; }
1023 var r = false;
1024 var glErr = 0;
1025 var err = 0;
1026 try { f(); } catch(e) { r=true; glErr = e.glError; }
1027 if (glErr === 0) {
1028 if (glErr === undefined) {
1029 testFailed("assertGLError: UNEXPCETED EXCEPTION", name, f);
1030 } else {
1031 testFailed("assertGLError: expected: " + getGLErrorAsString(gl, err) +
1032 " actual: " + getGLErrorAsString(gl, glErr), name, f);
1033 }
1034 return false;
1035 }
1036 return true;
1037 }
1038
1039 // Assert that f throws an exception but does not generate a GL error.
1040 function assertThrowNoGLError(gl, name, f) {
1041 if (f == null) { f = name; name = null; }
1042 var r = false;
1043 var glErr = undefined;
1044 var exp;
1045 try { f(); } catch(e) { r=true; glErr = e.glError; exp = e;}
1046 if (!r) {
1047 testFailed(
1048 "assertThrowNoGLError: should have thrown exception", name, f);
1049 return false;
1050 } else {
1051 if (glErr !== undefined) {
1052 testFailed(
1053 "assertThrowNoGLError: should be no GL error but generated: " +
1054 getGLErrorAsString(gl, glErr), name, f);
1055 return false;
1056 }
1057 }
1058 testPassed("assertThrowNoGLError", name, f);
1059 return true;
1060 }
1061
1062 Quad = {
1063 vertices : [
1064 -1,-1,0,
1065 1,-1,0,
1066 -1,1,0,
1067 1,-1,0,
1068 1,1,0,
1069 -1,1,0
1070 ],
1071 normals : [
1072 0,0,-1,
1073 0,0,-1,
1074 0,0,-1,
1075 0,0,-1,
1076 0,0,-1,
1077 0,0,-1
1078 ],
1079 texcoords : [
1080 0,0,
1081 1,0,
1082 0,1,
1083 1,0,
1084 1,1,
1085 0,1
1086 ],
1087 indices : [0,1,2,1,5,2],
1088 makeVBO : function(gl) {
1089 return new VBO(gl,
1090 {size:3, data: Quad.vertices},
1091 {size:3, data: Quad.normals},
1092 {size:2, data: Quad.texcoords}
1093 )
1094 },
1095 cache: {},
1096 getCachedVBO : function(gl) {
1097 if (!this.cache[gl])
1098 this.cache[gl] = this.makeVBO(gl);
1099 return this.cache[gl];
1100 }
1101 }
1102 Cube = {
1103 vertices : [ 0.5, -0.5, 0.5, // +X
1104 0.5, -0.5, -0.5,
1105 0.5, 0.5, -0.5,
1106 0.5, 0.5, 0.5,
1107
1108 0.5, 0.5, 0.5, // +Y
1109 0.5, 0.5, -0.5,
1110 -0.5, 0.5, -0.5,
1111 -0.5, 0.5, 0.5,
1112
1113 0.5, 0.5, 0.5, // +Z
1114 -0.5, 0.5, 0.5,
1115 -0.5, -0.5, 0.5,
1116 0.5, -0.5, 0.5,
1117
1118 -0.5, -0.5, 0.5, // -X
1119 -0.5, 0.5, 0.5,
1120 -0.5, 0.5, -0.5,
1121 -0.5, -0.5, -0.5,
1122
1123 -0.5, -0.5, 0.5, // -Y
1124 -0.5, -0.5, -0.5,
1125 0.5, -0.5, -0.5,
1126 0.5, -0.5, 0.5,
1127
1128 -0.5, -0.5, -0.5, // -Z
1129 -0.5, 0.5, -0.5,
1130 0.5, 0.5, -0.5,
1131 0.5, -0.5, -0.5,
1132 ],
1133
1134 normals : [ 1, 0, 0,
1135 1, 0, 0,
1136 1, 0, 0,
1137 1, 0, 0,
1138
1139 0, 1, 0,
1140 0, 1, 0,
1141 0, 1, 0,
1142 0, 1, 0,
1143
1144 0, 0, 1,
1145 0, 0, 1,
1146 0, 0, 1,
1147 0, 0, 1,
1148
1149 -1, 0, 0,
1150 -1, 0, 0,
1151 -1, 0, 0,
1152 -1, 0, 0,
1153
1154 0,-1, 0,
1155 0,-1, 0,
1156 0,-1, 0,
1157 0,-1, 0,
1158
1159 0, 0,-1,
1160 0, 0,-1,
1161 0, 0,-1,
1162 0, 0,-1
1163 ],
1164
1165 indices : [],
1166 create : function(){
1167 for (var i = 0; i < 6; i++) {
1168 Cube.indices.push(i*4 + 0);
1169 Cube.indices.push(i*4 + 1);
1170 Cube.indices.push(i*4 + 3);
1171 Cube.indices.push(i*4 + 1);
1172 Cube.indices.push(i*4 + 2);
1173 Cube.indices.push(i*4 + 3);
1174 }
1175 },
1176
1177 makeVBO : function(gl) {
1178 return new VBO(gl,
1179 {size:3, data: Cube.vertices},
1180 {size:3, data: Cube.normals},
1181 {elements: true, data: Cube.indices}
1182 )
1183 },
1184 cache : {},
1185 getCachedVBO : function(gl) {
1186 if (!this.cache[gl])
1187 this.cache[gl] = this.makeVBO(gl);
1188 return this.cache[gl];
1189 }
1190 }
1191 Cube.create();
1192
1193 Sphere = {
1194 vertices : [],
1195 normals : [],
1196 indices : [],
1197 create : function(){
1198 var r = 0.75;
1199 function vert(theta, phi)
1200 {
1201 var r = 0.75;
1202 var x, y, z, nx, ny, nz;
1203
1204 nx = Math.sin(theta) * Math.cos(phi);
1205 ny = Math.sin(phi);
1206 nz = Math.cos(theta) * Math.cos(phi);
1207 Sphere.normals.push(nx);
1208 Sphere.normals.push(ny);
1209 Sphere.normals.push(nz);
1210
1211 x = r * Math.sin(theta) * Math.cos(phi);
1212 y = r * Math.sin(phi);
1213 z = r * Math.cos(theta) * Math.cos(phi);
1214 Sphere.vertices.push(x);
1215 Sphere.vertices.push(y);
1216 Sphere.vertices.push(z);
1217 }
1218 for (var phi = -Math.PI/2; phi < Math.PI/2; phi += Math.PI/20) {
1219 var phi2 = phi + Math.PI/20;
1220 for (var theta = -Math.PI/2; theta <= Math.PI/2; theta += Math.PI/20) {
1221 vert(theta, phi);
1222 vert(theta, phi2);
1223 }
1224 }
1225 }
1226 }
1227
1228 Sphere.create();
1229
1230 initGL_CONTEXT_ID = function(){
1231 var c = document.createElement('canvas');
1232 var contextNames = ['webgl', 'experimental-webgl'];
1233 GL_CONTEXT_ID = null;
1234 for (var i=0; i<contextNames.length; i++) {
1235 try {
1236 if (c.getContext(contextNames[i])) {
1237 GL_CONTEXT_ID = contextNames[i];
1238 break;
1239 }
1240 } catch (e) {}
1241 }
1242 if (!GL_CONTEXT_ID) {
1243 log("No WebGL context found. Unable to run tests.");
1244 }
1245 }
1246
1247 initGL_CONTEXT_ID();
OLDNEW
« no previous file with comments | « conformance/more/unit.js ('k') | conformance/programs/00_test_list.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698