FRAMEBUFFER_INCOMPLETE_ATTACHMENT仅在Android w / Firefox上发生

时间:2016-03-20 01:40:38

标签: javascript cross-browser webgl framebuffer

我有一些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

1 个答案:

答案 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 /驱动程序/浏览器。