2 Copyright (c) 2020 The Khronos Group Inc.
3 Use of this source code is governed by an MIT-style license that can be
4 found in the LICENSE.txt file.
10 <meta charset=
"utf-8">
11 <title>WebGL2 can render to framebuffer attachments with different targets
</title>
12 <link rel=
"stylesheet" href=
"../../resources/js-test-style.css"/>
13 <script src=
"../../js/js-test-pre.js"></script>
14 <script src=
"../../js/webgl-test-utils.js"></script>
15 <script id=
"vshader" type=
"x-shader/x-vertex">#version
300 es
17 gl_Position = vec4(-
0.5, -
0.5,
0,
1);
21 <script id=
"fshader" type=
"x-shader/x-fragment">#version
300 es
22 precision mediump float;
25 outColor = vec4(
0,
1,
0,
1);
30 <canvas id=
"example" width=
"1",
height=
"1"></canvas>
31 <div id=
"description"></div>
32 <div id=
"console"></div>
37 description("Test framebuffer attachments with different targets");
39 const wtu
= WebGLTestUtils
;
40 const gl
= wtu
.create3DContext("example", undefined, 2);
43 testFailed("WebGL context creation failed");
45 testPassed("WebGL context creation succeeded");
49 function newResource(target
, mipLevels
, format
, size
) {
52 case gl
.RENDERBUFFER
: {
53 ret
= gl
.createRenderbuffer();
55 for (let i
= 1; i
< mipLevels
; i
++) {
56 ret
.mips
.push(gl
.createRenderbuffer());
58 for (const i
in ret
.mips
) {
59 const rb
= ret
.mips
[i
];
60 gl
.bindRenderbuffer(target
, rb
);
61 gl
.renderbufferStorage(target
, format
, size
>>i
, size
>>i
);
63 ret
.attach
= (attachEnum
, mipLevel
) => {
64 const rb
= ret
.mips
[mipLevel
];
65 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, attachEnum
, gl
.RENDERBUFFER
, rb
);
70 case gl
.TEXTURE_CUBE_MAP
: {
71 ret
= gl
.createTexture();
72 gl
.bindTexture(target
, ret
);
73 gl
.texStorage2D(target
, mipLevels
, format
, size
, size
);
74 let imageTarget
= target
;
75 if (imageTarget
== gl
.TEXTURE_CUBE_MAP
) {
76 imageTarget
= gl
.TEXTURE_CUBE_MAP_POSITIVE_X
+2; // Deliberately don't choose the first image.
78 ret
.attach
= (attachEnum
, mipLevel
) => {
79 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, attachEnum
, imageTarget
, ret
, mipLevel
);
84 case gl
.TEXTURE_2D_ARRAY
: {
85 ret
= gl
.createTexture();
86 gl
.bindTexture(target
, ret
);
87 gl
.texStorage3D(target
, mipLevels
, format
, size
, size
, 1);
88 ret
.attach
= (attachEnum
, mipLevel
) => {
89 gl
.framebufferTextureLayer(gl
.FRAMEBUFFER
, attachEnum
, ret
, mipLevel
, 0);
96 ret
.target
= wtu
.glEnumToString(gl
, target
);
97 ret
.format
= wtu
.glEnumToString(gl
, format
);
102 const MIP_LEVELS
= 2;
105 gl
.clearColor(1, 0, 0, 1);
107 const program
= wtu
.setupProgram(gl
, ['vshader','fshader'], [], console
.log
.bind(console
));
108 gl
.useProgram(program
);
110 const colorResList
= [
111 newResource(gl
.RENDERBUFFER
, MIP_LEVELS
, gl
.RGBA8
, SIZE
),
112 newResource(gl
.TEXTURE_2D
, MIP_LEVELS
, gl
.RGBA8
, SIZE
),
113 newResource(gl
.TEXTURE_CUBE_MAP
, MIP_LEVELS
, gl
.RGBA8
, SIZE
),
114 newResource(gl
.TEXTURE_3D
, MIP_LEVELS
, gl
.RGBA8
, SIZE
),
115 newResource(gl
.TEXTURE_2D_ARRAY
, MIP_LEVELS
, gl
.RGBA8
, SIZE
),
118 const depthResList
= [
119 newResource(gl
.RENDERBUFFER
, MIP_LEVELS
, gl
.DEPTH_COMPONENT16
, SIZE
),
120 newResource(gl
.TEXTURE_2D
, MIP_LEVELS
, gl
.DEPTH_COMPONENT16
, SIZE
),
121 newResource(gl
.TEXTURE_CUBE_MAP
, MIP_LEVELS
, gl
.DEPTH_COMPONENT16
, SIZE
),
122 //newResource(gl.TEXTURE_3D, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE), // Depth formats forbidden for TEXTURE_3D.
123 newResource(gl
.TEXTURE_2D_ARRAY
, MIP_LEVELS
, gl
.DEPTH_COMPONENT16
, SIZE
),
126 const fb
= gl
.createFramebuffer();
127 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fb
);
128 for (const color
of colorResList
) {
129 for (const depth
of depthResList
) {
130 debug(`\ncolor: ${color.target}; depth: ${depth.target}`);
131 for (let mipLevel
= 0; mipLevel
< MIP_LEVELS
; mipLevel
++) {
132 debug(`mipLevel: ${mipLevel}`);
133 color
.attach(gl
.COLOR_ATTACHMENT0
, mipLevel
);
134 depth
.attach(gl
.DEPTH_ATTACHMENT
, mipLevel
);
135 const maybeStatus
= wtu
.framebufferStatusShouldBe(gl
, gl
.FRAMEBUFFER
, [gl
.FRAMEBUFFER_COMPLETE
, gl
.FRAMEBUFFER_UNSUPPORTED
]);
136 if (!maybeStatus
|| maybeStatus
[0] != gl
.FRAMEBUFFER_COMPLETE
) {
140 gl
.clear(gl
.COLOR_BUFFER_BIT
);
141 wtu
.checkCanvas(gl
, [255, 0, 0, 255], `framebuffer layer ${mipLevel} should be cleared red`);
143 gl
.drawArrays(gl
.POINTS
, 0, 1);
144 wtu
.checkCanvas(gl
, [0, 255, 0, 255], `framebuffer layer ${mipLevel} should be drawn green`);
146 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, `No errors`);
151 // make sure we were not rendering to the canvas.
152 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, null)
153 wtu
.checkCanvas(gl
, [0, 0, 0, 0], "canvas should be zero");
157 var successfullyParsed
= true;
159 <script src=
"../../js/js-test-post.js"></script>