|
1 <!DOCTYPE HTML> |
|
2 <title>WebGL test: Drawing without attrib arrays</title> |
|
3 <script src="/tests/SimpleTest/SimpleTest.js"></script> |
|
4 <link rel="stylesheet" href="/tests/SimpleTest/test.css"> |
|
5 <script src="driver-info.js"></script> |
|
6 <script src="webgl-util.js"></script> |
|
7 <script id="vs-no-attrib" type="x-shader/x-vertex"> |
|
8 |
|
9 void main(void) { |
|
10 gl_PointSize = 64.0; |
|
11 gl_Position = vec4(vec3(0.0), 1.0); |
|
12 } |
|
13 |
|
14 </script> |
|
15 <script id="vs-attrib" type="x-shader/x-vertex"> |
|
16 |
|
17 attribute vec3 aPosition; |
|
18 |
|
19 void main(void) { |
|
20 gl_PointSize = 64.0; |
|
21 gl_Position = vec4(aPosition, 1.0); |
|
22 } |
|
23 |
|
24 </script> |
|
25 <script id="fs" type="x-shader/x-fragment"> |
|
26 |
|
27 precision mediump float; |
|
28 |
|
29 void main(void) { |
|
30 gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); |
|
31 } |
|
32 |
|
33 </script> |
|
34 <body> |
|
35 <canvas id="c" width="64" height="64"></canvas> |
|
36 <script> |
|
37 |
|
38 // Give ourselves a scope to return early from: |
|
39 (function() { |
|
40 var gl = WebGLUtil.getWebGL('c'); |
|
41 if (!gl) { |
|
42 todo(false, 'WebGL is unavailable.'); |
|
43 return; |
|
44 } |
|
45 |
|
46 function errorFunc(str) { |
|
47 ok(false, 'Error: ' + str); |
|
48 } |
|
49 WebGLUtil.setErrorFunc(errorFunc); |
|
50 WebGLUtil.setWarningFunc(errorFunc); |
|
51 |
|
52 var attribProg = WebGLUtil.createProgramByIds(gl, 'vs-attrib', 'fs'); |
|
53 var noAttribProg = WebGLUtil.createProgramByIds(gl, 'vs-no-attrib', 'fs'); |
|
54 if (!attribProg || !noAttribProg) { |
|
55 ok(false, 'Program linking should succeed.'); |
|
56 return; |
|
57 } |
|
58 |
|
59 attribProg.aPosition = gl.getAttribLocation(attribProg, "aPosition"); |
|
60 ok(attribProg.aPosition >= 0, '`aPosition` should be valid.'); |
|
61 |
|
62 function isScreenBlack() { |
|
63 var pixels = gl.drawingBufferWidth * gl.drawingBufferHeight; |
|
64 var data = new Uint8Array(4 * pixels); |
|
65 gl.readPixels(0, 0, |
|
66 gl.drawingBufferWidth, gl.drawingBufferHeight, |
|
67 gl.RGBA, gl.UNSIGNED_BYTE, |
|
68 data); |
|
69 |
|
70 var accum = 0; |
|
71 for (var i = 0; i < pixels; i++) { |
|
72 accum += data[4*i + 0]; |
|
73 accum += data[4*i + 1]; |
|
74 accum += data[4*i + 2]; |
|
75 } |
|
76 |
|
77 return accum == 0; |
|
78 } |
|
79 |
|
80 function checkGLError(func, info) { |
|
81 var error = gl.getError(); |
|
82 func(!error, '[' + info + '] gl.getError should be 0, was 0x' + error.toString(16) + '.'); |
|
83 } |
|
84 |
|
85 function testDrawing(info) { |
|
86 var cruelNumber = 1024*1024; |
|
87 // Really, we should test for INT32_MAX-1 here, but we don't gracefully chunk these calls, |
|
88 // and so try to create a VBO of size INT32_MAX-1 to pretend that vert attrib 0 is an array. |
|
89 // (INT32_MAX-1 because we check that `first+count` is a valid GLsizei, which is int32_t) |
|
90 var UINT16_MAX = 0xffff; |
|
91 var INT32_MAX = 0x7fffffff; |
|
92 var UINT32_MAX = 0xffffffff; |
|
93 |
|
94 // `first` needs room for `first+count` <= sizeof(GLsizei) == INT32_MAX |
|
95 var hugeFirst = Math.min(cruelNumber, INT32_MAX-1); |
|
96 var hugeIndex = Math.min(cruelNumber, UINT32_MAX); |
|
97 |
|
98 var indexType = gl.UNSIGNED_SHORT; |
|
99 var indexStride = 2; |
|
100 var indexArr = new Uint16Array([0, 1, Math.min(hugeIndex, UINT16_MAX)]); |
|
101 if (gl.getExtension('OES_element_index_uint')) { |
|
102 indexType = gl.UNSIGNED_INT; |
|
103 indexStride = 4; |
|
104 indexArr = new Uint32Array([0, 1, hugeIndex]); |
|
105 } |
|
106 |
|
107 gl.clear(gl.COLOR_BUFFER_BIT); |
|
108 gl.drawArrays(gl.POINTS, 0, 1); |
|
109 ok(!isScreenBlack(), '[' + info + '] drawArrays should color pixels.'); |
|
110 |
|
111 gl.clear(gl.COLOR_BUFFER_BIT); |
|
112 gl.drawArrays(gl.POINTS, hugeFirst, 1); |
|
113 ok(!isScreenBlack(), '[' + info + '] drawArrays[huge first] should color pixels.'); |
|
114 |
|
115 checkGLError(ok, info); |
|
116 |
|
117 var elemTestFunc = todo; // We fail on most implementations. |
|
118 var checkGLTestFunc = todo; |
|
119 if (DriverInfo.getDriver() == DriverInfo.DRIVER.ANGLE || |
|
120 DriverInfo.getOS() == DriverInfo.OS.ANDROID) |
|
121 { |
|
122 // ANGLE and Android slaves seem to work fine. |
|
123 elemTestFunc = ok; |
|
124 checkGLTestFunc = ok; |
|
125 } |
|
126 if (DriverInfo.getDriver() == DriverInfo.DRIVER.ANDROID_X86_EMULATOR || |
|
127 DriverInfo.getOS() == DriverInfo.OS.B2G) |
|
128 { |
|
129 // ...but the Android 4.2 x86 emulator environment is different |
|
130 elemTestFunc = todo; |
|
131 checkGLTestFunc = ok; |
|
132 } |
|
133 |
|
134 // Now for drawElements: |
|
135 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer()); |
|
136 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexArr, gl.STATIC_DRAW); |
|
137 |
|
138 gl.clear(gl.COLOR_BUFFER_BIT); |
|
139 gl.drawElements(gl.POINTS, 1, indexType, 0); |
|
140 elemTestFunc(!isScreenBlack(), '[' + info + '] drawElements[0] should color pixels.'); |
|
141 |
|
142 gl.clear(gl.COLOR_BUFFER_BIT); |
|
143 gl.drawElements(gl.POINTS, 1, indexType, 1*indexStride); |
|
144 elemTestFunc(!isScreenBlack(), '[' + info + '] drawElements[1] should color pixels.'); |
|
145 |
|
146 gl.clear(gl.COLOR_BUFFER_BIT); |
|
147 gl.drawElements(gl.POINTS, 1, indexType, 2*indexStride); |
|
148 elemTestFunc(!isScreenBlack(), '[' + info + '] drawElements[huge offset] should color pixels.'); |
|
149 |
|
150 checkGLError(checkGLTestFunc, info); |
|
151 } |
|
152 |
|
153 // Begin drawing |
|
154 gl.clearColor(0.0, 0.0, 0.0, 1.0); |
|
155 gl.disable(gl.DEPTH_TEST); |
|
156 |
|
157 // No-attrib prog: |
|
158 gl.useProgram(noAttribProg); |
|
159 testDrawing('no-attrib'); |
|
160 |
|
161 // One-attrib, no-array prog: |
|
162 gl.useProgram(attribProg); |
|
163 gl.disableVertexAttribArray(attribProg.aPosition); |
|
164 gl.vertexAttrib3fv(attribProg.aPosition, [0.0, 0.0, 0.0]); |
|
165 testDrawing('one-attrib, no-array'); |
|
166 })(); |
|
167 |
|
168 </script> |
|
169 |