OLD | NEW |
| (Empty) |
1 <!DOCTYPE html> | |
2 <html> | |
3 <head> | |
4 <meta charset="utf-8"> | |
5 <script src="../../../resources/js-test.js"></script> | |
6 <script src="resources/webgl-test.js"></script> | |
7 <script src="resources/webgl-test-utils.js"></script> | |
8 <title>WebGL WEBGL_depth_texture Conformance Tests</title> | |
9 </head> | |
10 <body> | |
11 <script id="vshader" type="x-shader/x-vertex"> | |
12 attribute vec4 a_position; | |
13 void main() | |
14 { | |
15 gl_Position = a_position; | |
16 } | |
17 </script> | |
18 | |
19 <script id="fshader" type="x-shader/x-fragment"> | |
20 precision mediump float; | |
21 uniform sampler2D u_texture; | |
22 uniform vec2 u_resolution; | |
23 void main() | |
24 { | |
25 vec2 texcoord = gl_FragCoord.xy / u_resolution; | |
26 gl_FragColor = texture2D(u_texture, texcoord); | |
27 } | |
28 </script> | |
29 <div id="description"></div> | |
30 <div id="console"></div> | |
31 <canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canv
as> | |
32 <script> | |
33 if (window.initNonKhronosFramework) { | |
34 window.initNonKhronosFramework(false); | |
35 } | |
36 description("This test verifies the functionality of the WEBGL_depth_texture ext
ension, if it is available."); | |
37 | |
38 debug(""); | |
39 | |
40 if (window.internals) | |
41 window.internals.settings.setWebGLErrorsToConsoleEnabled(false); | |
42 | |
43 var wtu = WebGLTestUtils; | |
44 var canvas = document.getElementById("canvas"); | |
45 var gl = wtu.create3DContext(canvas, {antialias: false}); | |
46 var program = wtu.setupTexturedQuad(gl); | |
47 var ext = null; | |
48 var vao = null; | |
49 var tex; | |
50 var name; | |
51 var supportedFormats; | |
52 | |
53 if (!gl) { | |
54 testFailed("WebGL context does not exist"); | |
55 } else { | |
56 testPassed("WebGL context exists"); | |
57 | |
58 // Run tests with extension disabled | |
59 runTestDisabled(); | |
60 | |
61 // Query the extension and store globally so shouldBe can access it | |
62 ext = gl.getExtension("WEBGL_depth_texture"); | |
63 if (!ext) { | |
64 testPassed("No WEBGL_depth_texture support -- this is legal"); | |
65 runSupportedTest(false); | |
66 } else { | |
67 testPassed("Successfully enabled WEBGL_depth_texture extension"); | |
68 | |
69 runSupportedTest(true); | |
70 runTestExtension(); | |
71 } | |
72 } | |
73 | |
74 function runSupportedTest(extensionEnabled) { | |
75 var name = wtu.getSupportedExtensionWithKnownPrefixes(gl, "WEBGL_depth_textu
re"); | |
76 if (name !== undefined) { | |
77 if (extensionEnabled) { | |
78 testPassed("WEBGL_depth_texture listed as supported and getExtension
succeeded"); | |
79 } else { | |
80 testFailed("WEBGL_depth_texture listed as supported but getExtension
failed"); | |
81 } | |
82 } else { | |
83 if (extensionEnabled) { | |
84 testFailed("WEBGL_depth_texture not listed as supported but getExten
sion succeeded"); | |
85 } else { | |
86 testPassed("WEBGL_depth_texture not listed as supported and getExten
sion failed -- this is legal"); | |
87 } | |
88 } | |
89 } | |
90 | |
91 | |
92 function runTestDisabled() { | |
93 debug("Testing binding enum with extension disabled"); | |
94 | |
95 var tex = gl.createTexture(); | |
96 gl.bindTexture(gl.TEXTURE_2D, tex); | |
97 shouldGenerateGLError(gl, [gl.INVALID_ENUM, gl.INVALID_VALUE], 'gl.texImage2
D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED
_SHORT, null)'); | |
98 shouldGenerateGLError(gl, [gl.INVALID_ENUM, gl.INVALID_VALUE], 'gl.texImage2
D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED
_INT, null)'); | |
99 } | |
100 | |
101 | |
102 function dumpIt(gl, res, msg) { | |
103 return; // comment out to debug | |
104 debug(msg); | |
105 var actualPixels = new Uint8Array(res * res * 4); | |
106 gl.readPixels(0, 0, res, res, gl.RGBA, gl.UNSIGNED_BYTE, actualPixels); | |
107 | |
108 for (var yy = 0; yy < res; ++yy) { | |
109 var strs = []; | |
110 for (var xx = 0; xx < res; ++xx) { | |
111 var actual = (yy * res + xx) * 4; | |
112 strs.push("(" + actualPixels[actual] + "," + actualPixels[actual+1] + ","
+ actualPixels[actual + 2] + "," + actualPixels[actual + 3] + ")"); | |
113 } | |
114 debug(strs.join(" ")); | |
115 } | |
116 } | |
117 function runTestExtension() { | |
118 debug("Testing WEBGL_depth_texture"); | |
119 | |
120 var res = 8; | |
121 | |
122 // make canvas for testing. | |
123 canvas2 = document.createElement("canvas"); | |
124 canvas2.width = res; | |
125 canvas2.height = res; | |
126 var ctx = canvas2.getContext("2d"); | |
127 ctx.fillStyle = "blue"; | |
128 ctx.fillRect(0, 0, canvas2.width, canvas2.height); | |
129 | |
130 var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_position']); | |
131 gl.useProgram(program); | |
132 gl.uniform2f(gl.getUniformLocation(program, "u_resolution"), res, res); | |
133 | |
134 var buffer = gl.createBuffer(); | |
135 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | |
136 gl.bufferData( | |
137 gl.ARRAY_BUFFER, | |
138 new Float32Array( | |
139 [ 1, 1, 1, | |
140 -1, 1, 0, | |
141 -1, -1, -1, | |
142 1, 1, 1, | |
143 -1, -1, -1, | |
144 1, -1, 0, | |
145 ]), | |
146 gl.STATIC_DRAW); | |
147 gl.enableVertexAttribArray(0); | |
148 gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); | |
149 | |
150 var types = [ | |
151 {obj: 'gl', attachment: 'DEPTH_ATTACHMENT', format: 'DEPTH_COMP
ONENT', type: 'UNSIGNED_SHORT', data: 'new Uint16Array(1)' }, | |
152 {obj: 'gl', attachment: 'DEPTH_ATTACHMENT', format: 'DEPTH_COMP
ONENT', type: 'UNSIGNED_INT', data: 'new Uint32Array(1)' }, | |
153 {obj: 'ext', attachment: 'DEPTH_STENCIL_ATTACHMENT', format: 'DEPTH_STEN
CIL', type: 'UNSIGNED_INT_24_8_WEBGL', data: 'new Uint32Array(1)' } | |
154 ]; | |
155 | |
156 for (var ii = 0; ii < types.length; ++ii) { | |
157 var typeInfo = types[ii]; | |
158 var type = typeInfo.type; | |
159 var typeStr = typeInfo.obj + '.' + type; | |
160 | |
161 debug(""); | |
162 debug("testing: " + type); | |
163 | |
164 // check that cubemaps are not allowed. | |
165 var cubeTex = gl.createTexture(); | |
166 gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeTex); | |
167 var targets = [ | |
168 'TEXTURE_CUBE_MAP_POSITIVE_X', | |
169 'TEXTURE_CUBE_MAP_NEGATIVE_X', | |
170 'TEXTURE_CUBE_MAP_POSITIVE_Y', | |
171 'TEXTURE_CUBE_MAP_NEGATIVE_Y', | |
172 'TEXTURE_CUBE_MAP_POSITIVE_Z', | |
173 'TEXTURE_CUBE_MAP_NEGATIVE_Z' | |
174 ]; | |
175 for (var tt = 0; tt < targets.length; ++tt) { | |
176 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.'
+ targets[ii] + ', 1, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.forma
t + ', ' + typeStr + ', null)'); | |
177 } | |
178 | |
179 // check 2d textures. | |
180 tex = gl.createTexture(); | |
181 gl.bindTexture(gl.TEXTURE_2D, tex); | |
182 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); | |
183 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); | |
184 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); | |
185 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); | |
186 | |
187 // test level > 0 | |
188 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.TEXTUR
E_2D, 1, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + ty
peStr + ', null)'); | |
189 | |
190 // test with data | |
191 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.TEXTUR
E_2D, 0, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + ty
peStr + ', ' + typeInfo.data + ')'); | |
192 | |
193 // test with canvas | |
194 shouldGenerateGLError(gl, [gl.INVALID_VALUE, gl.INVALID_ENUM, gl.INVALID
_OPERATION], 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', gl.' +
typeInfo.format + ', ' + typeStr + ', canvas2)'); | |
195 | |
196 // test copyTexImage2D | |
197 shouldGenerateGLError(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], 'gl.c
opyTexImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', 0, 0, 1, 1, 0)'); | |
198 | |
199 // test real thing | |
200 shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.texImage2D(gl.TEXTURE_2D, 0,
gl.' + typeInfo.format + ', ' + res + ', ' + res + ', 0, gl.' + typeInfo.format
+ ', ' + typeStr + ', null)'); | |
201 | |
202 // test texSubImage2D | |
203 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texSubImage2D(gl.TEX
TURE_2D, 0, 0, 0, 1, 1, gl.' + typeInfo.format + ', ' + typeStr + ', ' + typeIn
fo.data + ')'); | |
204 | |
205 // test copyTexSubImage2D | |
206 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.copyTexSubImage2D(gl
.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1)'); | |
207 | |
208 // test generateMipmap | |
209 shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.generateMipmap(gl.TE
XTURE_2D)'); | |
210 | |
211 var fbo = gl.createFramebuffer(); | |
212 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); | |
213 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl[typeInfo.attachment], gl.TEXT
URE_2D, tex, 0); | |
214 // TODO: remove this check if the spec is updated to require these combi
nations to work. | |
215 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE
) | |
216 { | |
217 // try adding a color buffer. | |
218 var colorTex = gl.createTexture(); | |
219 gl.bindTexture(gl.TEXTURE_2D, colorTex); | |
220 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
; | |
221 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
; | |
222 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); | |
223 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); | |
224 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, res, res, 0, gl.RGBA, gl.UN
SIGNED_BYTE, null); | |
225 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEX
TURE_2D, colorTex, 0); | |
226 } | |
227 | |
228 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_CO
MPLETE'); | |
229 | |
230 // use the default texture to render with while we return to the depth t
exture. | |
231 gl.bindTexture(gl.TEXTURE_2D, null); | |
232 | |
233 // render the z-quad | |
234 gl.enable(gl.DEPTH_TEST); | |
235 gl.clearColor(1, 0, 0, 1); | |
236 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); | |
237 gl.drawArrays(gl.TRIANGLES, 0, 6); | |
238 | |
239 dumpIt(gl, res, "--first--"); | |
240 | |
241 // render the depth texture. | |
242 gl.bindFramebuffer(gl.FRAMEBUFFER, null); | |
243 gl.bindTexture(gl.TEXTURE_2D, tex); | |
244 gl.clearColor(0, 0, 1, 1); | |
245 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); | |
246 gl.drawArrays(gl.TRIANGLES, 0, 6); | |
247 | |
248 var actualPixels = new Uint8Array(res * res * 4); | |
249 gl.readPixels(0, 0, res, res, gl.RGBA, gl.UNSIGNED_BYTE, actualPixels); | |
250 | |
251 dumpIt(gl, res, "--depth--"); | |
252 | |
253 // Check that each pixel's RGB are the same and that it's value is less | |
254 // than the previous pixel in either direction. Basically verify we have
a | |
255 // gradient. | |
256 var success = true; | |
257 for (var yy = 0; yy < res; ++yy) { | |
258 for (var xx = 0; xx < res; ++xx) { | |
259 var actual = (yy * res + xx) * 4; | |
260 var left = actual - 4; | |
261 var down = actual - res * 4; | |
262 | |
263 if (actualPixels[actual + 0] != actualPixels[actual + 1]) { | |
264 testFailed('R != G'); | |
265 success = false; | |
266 } | |
267 if (actualPixels[actual + 0] != actualPixels[actual + 2]) { | |
268 testFailed('R != B'); | |
269 success = false; | |
270 } | |
271 // ALPHA is implementation dependent | |
272 if (actualPixels[actual + 3] != 0xFF && actualPixels[actual + 3] !=
actualPixels[actual + 0]) { | |
273 testFailed('A != 255 && A != R'); | |
274 success = false; | |
275 } | |
276 | |
277 if (xx > 0) { | |
278 if (actualPixels[actual] <= actualPixels[left]) { | |
279 testFailed("actual(" + actualPixels[actual] + ") < left(" + ac
tualPixels[left] + ")"); | |
280 success = false; | |
281 } | |
282 } | |
283 if (yy > 0) { | |
284 if (actualPixels[actual] <= actualPixels[down]) { | |
285 testFailed("actual(" + actualPixels[actual] + ") < down(" +
actualPixels[down] + ")"); | |
286 success = false; | |
287 } | |
288 } | |
289 } | |
290 } | |
291 | |
292 // Check that bottom left corner is vastly different thatn top right. | |
293 if (actualPixels[(res * res - 1) * 4] - actualPixels[0] < 0xC0) { | |
294 testFailed("corners are not different enough"); | |
295 success = false; | |
296 } | |
297 | |
298 if (success) { | |
299 testPassed("depth texture rendered correctly."); | |
300 } | |
301 | |
302 // check limitations | |
303 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); | |
304 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl[typeInfo.attachment], gl.TEXT
URE_2D, null, 0); | |
305 var badAttachment = typeInfo.attachment == 'DEPTH_ATTACHMENT' ? 'DEPTH_S
TENCIL_ATTACHMENT' : 'DEPTH_ATTACHMENT'; | |
306 shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.framebufferTexture2D(gl.FRAME
BUFFER, gl.' + badAttachment + ', gl.TEXTURE_2D, tex, 0)'); | |
307 shouldNotBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER
_COMPLETE'); | |
308 shouldGenerateGLError(gl, gl.INVALID_FRAMEBUFFER_OPERATION, 'gl.clear(gl
.DEPTH_BUFFER_BIT)'); | |
309 gl.bindFramebuffer(gl.FRAMEBUFFER, null); | |
310 shouldBe('gl.getError()', 'gl.NO_ERROR'); | |
311 } | |
312 } | |
313 | |
314 debug(""); | |
315 successfullyParsed = true; | |
316 if (window.nonKhronosFrameworkNotifyDone) { | |
317 window.nonKhronosFrameworkNotifyDone(); | |
318 } | |
319 </script> | |
320 </body> | |
321 </html> | |
OLD | NEW |