FRAMEBUFFER_INCOMPLETE_ATTACHMENT 只发生在 Android w/ Firefox
FRAMEBUFFER_INCOMPLETE_ATTACHMENT only happens on Android w/ Firefox
我有一些 javascript/webgl 代码可以在我尝试过的所有浏览器上运行,但 Android 上的移动版 firefox 运行 除外。问题与“framebuffer complete”有关,但我不知道具体是什么问题。
这是我能制作的最小的复制品。它应该只是创建一个纹理和一个帧缓冲区,设置一些属性,然后检查帧缓冲区是 'complete':
var canvas = document.createElement('canvas');
var gl = canvas.getContext('webgl');
var GL = WebGLRenderingContext;
if (gl.getExtension('OES_texture_float') === null) {
alert("No float support.");
}
var texture = gl.createTexture();
var frameBuffer = gl.createFramebuffer();
gl.bindTexture(GL.TEXTURE_2D, texture);
gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
gl.texImage2D(
GL.TEXTURE_2D, //target
0, //level
GL.RGBA, //internalformat
2, //width
2, //height
0, //border
GL.RGBA, //format
GL.FLOAT, // type [changing to UNSIGNED_BYTE "fixes" the failure...?]
null // pixels
);
gl.framebufferTexture2D(
GL.FRAMEBUFFER,
GL.COLOR_ATTACHMENT0,
GL.TEXTURE_2D,
texture,
0);
var result = gl.checkFramebufferStatus(GL.FRAMEBUFFER);
if (result === GL.FRAMEBUFFER_COMPLETE) {
alert("success (FRAMEBUFFER_COMPLETE)");
} else {
alert("ERROR " + ({
[0]: "Argument wasn't a frame buffer",
[GL.INVALID_ENUM]: "INVALID_ENUM",
[GL.FRAMEBUFFER_INCOMPLETE_ATTACHMENT]: "FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
[GL.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT]:
"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
[GL.FRAMEBUFFER_INCOMPLETE_DIMENSIONS]: "FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
[GL.FRAMEBUFFER_UNSUPPORTED]: "FRAMEBUFFER_UNSUPPORTED"
}[result] || result));
}
在我的测试中,此代码在 Windows+Firefox-44、Windows+Chrome-49、Android+Chrome 和Ubuntu+火狐。但在 Android+Firefox 上 FRAMEBUFFER_INCOMPLETE_ATTACHMENT
失败。
此外,我发现它似乎只影响 FLOAT
纹理。如果我将类型更改为 UNSIGNED_BYTE
,它会通过。
因为我一般不熟悉 opengl,所以我可能做了一些明显的疏忽(例如,没有绑定必需的 属性),而移动版 firefox 是唯一没有静默的浏览器纠正我的错误。
另一个可能相关的事情是必须将 GL.FRAMEBUFFER
传递给 gl.checkFramebufferStatus
,而不是实际的 frameBuffer
实例。当我传递 frameBuffer
时,结果总是 0。通常 0 表示成功,但是 the mdn docs 甚至没有将 0 列为此函数的可能 return 值;他们说好的结果是 FRAMEBUFFER_COMPLETE
.
如果它在其他浏览器中 在完全相同的 phone 上工作,那么我会 file a bug with Mozilla.
但一般来说,将浮点纹理附加到帧缓冲区的功能并未得到普遍支持。在 OpenGL ES 2.0 中,任何格式都不能保证有效:(
在 WebGL 中,只有 3 种格式可以保证有效。 From the spec:
The following combinations of framebuffer object attachments, when all of the attachments are framebuffer attachment complete, non-zero, and have the same width and height, must result in the framebuffer being framebuffer complete:
- COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture
- COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_ATTACHMENT = DEPTH_COMPONENT16 renderbuffer
- COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL renderbuffer
所有其他附件组合最多为 GPU/driver/browser。
我有一些 javascript/webgl 代码可以在我尝试过的所有浏览器上运行,但 Android 上的移动版 firefox 运行 除外。问题与“framebuffer complete”有关,但我不知道具体是什么问题。
这是我能制作的最小的复制品。它应该只是创建一个纹理和一个帧缓冲区,设置一些属性,然后检查帧缓冲区是 'complete':
var canvas = document.createElement('canvas');
var gl = canvas.getContext('webgl');
var GL = WebGLRenderingContext;
if (gl.getExtension('OES_texture_float') === null) {
alert("No float support.");
}
var texture = gl.createTexture();
var frameBuffer = gl.createFramebuffer();
gl.bindTexture(GL.TEXTURE_2D, texture);
gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
gl.texImage2D(
GL.TEXTURE_2D, //target
0, //level
GL.RGBA, //internalformat
2, //width
2, //height
0, //border
GL.RGBA, //format
GL.FLOAT, // type [changing to UNSIGNED_BYTE "fixes" the failure...?]
null // pixels
);
gl.framebufferTexture2D(
GL.FRAMEBUFFER,
GL.COLOR_ATTACHMENT0,
GL.TEXTURE_2D,
texture,
0);
var result = gl.checkFramebufferStatus(GL.FRAMEBUFFER);
if (result === GL.FRAMEBUFFER_COMPLETE) {
alert("success (FRAMEBUFFER_COMPLETE)");
} else {
alert("ERROR " + ({
[0]: "Argument wasn't a frame buffer",
[GL.INVALID_ENUM]: "INVALID_ENUM",
[GL.FRAMEBUFFER_INCOMPLETE_ATTACHMENT]: "FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
[GL.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT]:
"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
[GL.FRAMEBUFFER_INCOMPLETE_DIMENSIONS]: "FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
[GL.FRAMEBUFFER_UNSUPPORTED]: "FRAMEBUFFER_UNSUPPORTED"
}[result] || result));
}
在我的测试中,此代码在 Windows+Firefox-44、Windows+Chrome-49、Android+Chrome 和Ubuntu+火狐。但在 Android+Firefox 上 FRAMEBUFFER_INCOMPLETE_ATTACHMENT
失败。
此外,我发现它似乎只影响 FLOAT
纹理。如果我将类型更改为 UNSIGNED_BYTE
,它会通过。
因为我一般不熟悉 opengl,所以我可能做了一些明显的疏忽(例如,没有绑定必需的 属性),而移动版 firefox 是唯一没有静默的浏览器纠正我的错误。
另一个可能相关的事情是必须将 GL.FRAMEBUFFER
传递给 gl.checkFramebufferStatus
,而不是实际的 frameBuffer
实例。当我传递 frameBuffer
时,结果总是 0。通常 0 表示成功,但是 the mdn docs 甚至没有将 0 列为此函数的可能 return 值;他们说好的结果是 FRAMEBUFFER_COMPLETE
.
如果它在其他浏览器中 在完全相同的 phone 上工作,那么我会 file a bug with Mozilla.
但一般来说,将浮点纹理附加到帧缓冲区的功能并未得到普遍支持。在 OpenGL ES 2.0 中,任何格式都不能保证有效:(
在 WebGL 中,只有 3 种格式可以保证有效。 From the spec:
The following combinations of framebuffer object attachments, when all of the attachments are framebuffer attachment complete, non-zero, and have the same width and height, must result in the framebuffer being framebuffer complete:
- COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture
- COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_ATTACHMENT = DEPTH_COMPONENT16 renderbuffer
- COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL renderbuffer
所有其他附件组合最多为 GPU/driver/browser。