为什么在webgl2中从16字节缓冲区创建2x8 R8纹理失败?

时间:2017-11-17 18:34:39

标签: webgl2

当我尝试在webgl2中创建2x8 R8纹理时,出现错误。对于4x8纹理,这不会发生。如果我将输入缓冲区的大小与我预期的相比加倍,则2x8会成功。

webgl2是否具有'列对齐'创建/阅读纹理时的4个?

以下是一些可以重现问题的代码。我在Chrome和Firefox上都在Windows上测试过它:



function test_read(w) {
    let gl = document.createElement('canvas').getContext('webgl2');
    let h = 8;
    let data = new Uint8Array(w*h);
    data[5] = 5;

    let texture = gl.createTexture();
    let frameBuffer = gl.createFramebuffer();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8, w, h, 0, gl.RED, gl.UNSIGNED_BYTE, data);
    if (gl.getError() !== gl.NO_ERROR) {
        return 'bad w=' + w;
    }
    return 'good w=' + w;
}

console.log(test_read(4)); // good w=4
console.log(test_read(2)); // bad w=2




出现的错误代码是0x502(INVALID_OPERATION)。当读取通过扩展缓冲区创建的纹理时会发生类似的问题:它似乎期望列对齐' 4。

1 个答案:

答案 0 :(得分:2)

您需要设置gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1)

默认UNPACK_ALIGNMENT为4,这意味着WebGL期望每行像素为4个字节的倍数。由于您使用的是R8(1字节像素)且宽度为2,因此您的行只有2个字节长。当您将宽度更改为4时,它将开始工作。

function test_read(w) {
    let gl = document.createElement('canvas').getContext('webgl2');
    let h = 8;
    let data = new Uint8Array(w*h);
    data[5] = 5;

    // ---=== ADDED ===---
    gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);

    let texture = gl.createTexture();
    let frameBuffer = gl.createFramebuffer();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8, w, h, 0, gl.RED, gl.UNSIGNED_BYTE, data);
    if (gl.getError() !== gl.NO_ERROR) {
        return 'bad w=' + w;
    }
    return 'good w=' + w;
}

console.log(test_read(4)); // good w=4
console.log(test_read(2)); // bad w=2