我有一些javascript / webgl代码可以在我尝试的每个浏览器上运行,除了在Android上运行的Firefox的移动版本。这个问题与“framebuffer 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 + Firefox上成功完成。但它在Android + Firefox上以FRAMEBUFFER_INCOMPLETE_ATTACHMENT
失败。
另外,我发现它似乎只影响FLOAT
纹理。如果我将类型更改为UNSIGNED_BYTE
,则会传递。
因为我一般不熟悉opengl,所以我可能已经做了一些明显的疏忽(例如没有绑定必需的属性),而且移动firefox是唯一没有默默修复我的错误的浏览器。
另一个可能相关的事情是必须将GL.FRAMEBUFFER
传递给gl.checkFramebufferStatus
,而不是实际的frameBuffer
实例。当我传递frameBuffer
时,结果总是为0.通常0表示成功,但the mdn docs甚至不列出0作为此函数的可能返回值;他们说好的结果是FRAMEBUFFER_COMPLETE
。
答案 0 :(得分:2)
如果它在其他浏览器中的完全在同一部手机上工作,那么我会file a bug with Mozilla。
一般而言,将浮点纹理附加到帧缓冲区的功能并非普遍支持。在OpenGL ES 2.0中,没有任何格式可以保证工作:(
在WebGL中,只保证3种格式可以使用。 From the spec:
以下帧缓冲对象附件的组合,当所有附件都是帧缓冲附件完成,非零且具有相同的宽度和高度时,必须导致帧缓冲完成帧缓冲:
- COLOR_ATTACHMENT0 = RGBA / UNSIGNED_BYTE纹理
- COLOR_ATTACHMENT0 = RGBA / UNSIGNED_BYTE纹理+ DEPTH_ATTACHMENT = DEPTH_COMPONENT16渲染缓冲区
- COLOR_ATTACHMENT0 = RGBA / UNSIGNED_BYTE纹理+ DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL渲染缓冲区
所有其他附件组合均取决于GPU /驱动程序/浏览器。