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>
11 <script id=
"vshader" type=
"x-shader/x-vertex">
12 attribute vec4 a_position;
15 gl_Position = a_position;
19 <script id=
"fshader" type=
"x-shader/x-fragment">
20 precision mediump float;
21 uniform sampler2D u_texture;
22 uniform vec2 u_resolution;
25 vec2 texcoord = gl_FragCoord.xy / u_resolution;
26 gl_FragColor = texture2D(u_texture, texcoord);
29 <div id=
"description"></div>
30 <div id=
"console"></div>
31 <canvas id=
"canvas" width=
"8" height=
"8" style=
"width: 8px; height: 8px;"></canvas>
33 if (window
.initNonKhronosFramework
) {
34 window
.initNonKhronosFramework(false);
36 description("This test verifies the functionality of the WEBGL_depth_texture extension, if it is available.");
41 window
.internals
.settings
.setWebGLErrorsToConsoleEnabled(false);
43 var wtu
= WebGLTestUtils
;
44 var canvas
= document
.getElementById("canvas");
45 var gl
= wtu
.create3DContext(canvas
, {antialias
: false});
46 var program
= wtu
.setupTexturedQuad(gl
);
54 testFailed("WebGL context does not exist");
56 testPassed("WebGL context exists");
58 // Run tests with extension disabled
61 // Query the extension and store globally so shouldBe can access it
62 ext
= gl
.getExtension("WEBGL_depth_texture");
64 testPassed("No WEBGL_depth_texture support -- this is legal");
65 runSupportedTest(false);
67 testPassed("Successfully enabled WEBGL_depth_texture extension");
69 runSupportedTest(true);
74 function runSupportedTest(extensionEnabled
) {
75 var name
= wtu
.getSupportedExtensionWithKnownPrefixes(gl
, "WEBGL_depth_texture");
76 if (name
!== undefined) {
77 if (extensionEnabled
) {
78 testPassed("WEBGL_depth_texture listed as supported and getExtension succeeded");
80 testFailed("WEBGL_depth_texture listed as supported but getExtension failed");
83 if (extensionEnabled
) {
84 testFailed("WEBGL_depth_texture not listed as supported but getExtension succeeded");
86 testPassed("WEBGL_depth_texture not listed as supported and getExtension failed -- this is legal");
92 function runTestDisabled() {
93 debug("Testing binding enum with extension disabled");
95 var tex
= gl
.createTexture();
96 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
97 shouldGenerateGLError(gl
, gl
.INVALID_ENUM
, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null)');
98 shouldGenerateGLError(gl
, gl
.INVALID_ENUM
, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null)');
102 function dumpIt(gl
, res
, msg
) {
103 return; // comment out to debug
105 var actualPixels
= new Uint8Array(res
* res
* 4);
106 gl
.readPixels(0, 0, res
, res
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, actualPixels
);
108 for (var yy
= 0; yy
< res
; ++yy
) {
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] + ")");
114 debug(strs
.join(" "));
117 function runTestExtension() {
118 debug("Testing WEBGL_depth_texture");
122 // make canvas for testing.
123 canvas2
= document
.createElement("canvas");
125 canvas2
.height
= res
;
126 var ctx
= canvas2
.getContext("2d");
127 ctx
.fillStyle
= "blue";
128 ctx
.fillRect(0, 0, canvas2
.width
, canvas2
.height
);
130 var program
= wtu
.setupProgram(gl
, ['vshader', 'fshader'], ['a_position']);
131 gl
.useProgram(program
);
132 gl
.uniform2f(gl
.getUniformLocation(program
, "u_resolution"), res
, res
);
134 var buffer
= gl
.createBuffer();
135 gl
.bindBuffer(gl
.ARRAY_BUFFER
, buffer
);
147 gl
.enableVertexAttribArray(0);
148 gl
.vertexAttribPointer(0, 3, gl
.FLOAT
, false, 0, 0);
151 {obj
: 'gl', attachment
: 'DEPTH_ATTACHMENT', format
: 'DEPTH_COMPONENT', type
: 'UNSIGNED_SHORT', data
: 'new Uint16Array(1)' },
152 {obj
: 'gl', attachment
: 'DEPTH_ATTACHMENT', format
: 'DEPTH_COMPONENT', type
: 'UNSIGNED_INT', data
: 'new Uint32Array(1)' },
153 {obj
: 'ext', attachment
: 'DEPTH_STENCIL_ATTACHMENT', format
: 'DEPTH_STENCIL', type
: 'UNSIGNED_INT_24_8_WEBGL', data
: 'new Uint32Array(1)' }
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
;
162 debug("testing: " + type
);
164 // check that cubemaps are not allowed.
165 var cubeTex
= gl
.createTexture();
166 gl
.bindTexture(gl
.TEXTURE_CUBE_MAP
, cubeTex
);
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'
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
.format
+ ', ' + typeStr
+ ', null)');
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
);
188 shouldGenerateGLError(gl
, gl
.INVALID_OPERATION
, 'gl.texImage2D(gl.TEXTURE_2D, 1, gl.' + typeInfo
.format
+ ', 1, 1, 0, gl.' + typeInfo
.format
+ ', ' + typeStr
+ ', null)');
191 shouldGenerateGLError(gl
, gl
.INVALID_OPERATION
, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo
.format
+ ', 1, 1, 0, gl.' + typeInfo
.format
+ ', ' + typeStr
+ ', ' + typeInfo
.data
+ ')');
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)');
196 // test copyTexImage2D
197 shouldGenerateGLError(gl
, [gl
.INVALID_ENUM
, gl
.INVALID_OPERATION
], 'gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo
.format
+ ', 0, 0, 1, 1, 0)');
200 shouldGenerateGLError(gl
, gl
.NO_ERROR
, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo
.format
+ ', ' + res
+ ', ' + res
+ ', 0, gl.' + typeInfo
.format
+ ', ' + typeStr
+ ', null)');
202 // test texSubImage2D
203 shouldGenerateGLError(gl
, gl
.INVALID_OPERATION
, 'gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.' + typeInfo
.format
+ ', ' + typeStr
+ ', ' + typeInfo
.data
+ ')');
205 // test copyTexSubImage2D
206 shouldGenerateGLError(gl
, gl
.INVALID_OPERATION
, 'gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1)');
208 // test generateMipmap
209 shouldGenerateGLError(gl
, gl
.INVALID_OPERATION
, 'gl.generateMipmap(gl.TEXTURE_2D)');
211 var fbo
= gl
.createFramebuffer();
212 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
213 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
[typeInfo
.attachment
], gl
.TEXTURE_2D
, tex
, 0);
214 // TODO: remove this check if the spec is updated to require these combinations to work.
215 if (gl
.checkFramebufferStatus(gl
.FRAMEBUFFER
) != gl
.FRAMEBUFFER_COMPLETE
)
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
.UNSIGNED_BYTE
, null);
225 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, colorTex
, 0);
228 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
230 // use the default texture to render with while we return to the depth texture.
231 gl
.bindTexture(gl
.TEXTURE_2D
, null);
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);
239 dumpIt(gl
, res
, "--first--");
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);
248 var actualPixels
= new Uint8Array(res
* res
* 4);
249 gl
.readPixels(0, 0, res
, res
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, actualPixels
);
251 dumpIt(gl
, res
, "--depth--");
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
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;
263 if (actualPixels
[actual
+ 0] != actualPixels
[actual
+ 1]) {
264 testFailed('R != G');
267 if (actualPixels
[actual
+ 0] != actualPixels
[actual
+ 2]) {
268 testFailed('R != B');
271 // ALPHA is implementation dependent
272 if (actualPixels
[actual
+ 3] != 0xFF && actualPixels
[actual
+ 3] != actualPixels
[actual
+ 0]) {
273 testFailed('A != 255 && A != R');
278 if (actualPixels
[actual
] <= actualPixels
[left
]) {
279 testFailed("actual(" + actualPixels
[actual
] + ") < left(" + actualPixels
[left
] + ")");
284 if (actualPixels
[actual
] <= actualPixels
[down
]) {
285 testFailed("actual(" + actualPixels
[actual
] + ") < down(" + actualPixels
[down
] + ")");
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");
299 testPassed("depth texture rendered correctly.");
303 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
304 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
[typeInfo
.attachment
], gl
.TEXTURE_2D
, null, 0);
305 var badAttachment
= typeInfo
.attachment
== 'DEPTH_ATTACHMENT' ? 'DEPTH_STENCIL_ATTACHMENT' : 'DEPTH_ATTACHMENT';
306 shouldGenerateGLError(gl
, gl
.NO_ERROR
, 'gl.framebufferTexture2D(gl.FRAMEBUFFER, 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');
315 successfullyParsed
= true;
316 if (window
.nonKhronosFrameworkNotifyDone
) {
317 window
.nonKhronosFrameworkNotifyDone();