texImage2D接受什么样的数据?

时间:2016-07-20 09:10:24

标签: javascript webgl

我想使用WebGL将一些矩阵计算卸载到片段着色器。

我尝试使用texImage2D将我的矩阵作为RGB 2D纹理发送,但我不知道必须如何格式化数据。

我试过这个(对于一个2x2的正方形矩阵):

var textureData = new Uint8Array([
  0, 0, 0,  1, 0, 0,
  2, 0, 0,  3, 0, 0
]);
//...
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
  textureData);

但是我收到以下错误:

  

未捕获的TypeError:无法执行' texImage2D'上   ' WebGLRenderingContext':找不到匹配的功能   提供签名。

2 个答案:

答案 0 :(得分:1)

  

我正在尝试将矩阵作为RGB 2D纹理发送

我担心UNSIGNED_BYTE无法为此提供足够的精度,您可能希望使用OES_texture_float扩展名并将纹理创建为浮点纹理。

  

我不知道数据必须如何格式化

可以在spec

中找到texImage2D的可用签名
void texImage2D(
    GLenum target,
    GLint level,
    GLint internalformat,
    GLsizei width,
    GLsizei height,
    GLint border,
    GLenum format,
    GLenum type,
    ArrayBufferView? pixels
);

void texImage2D(
    GLenum target,
    GLint level,
    GLint internalformat,
    GLenum format,
    GLenum type,
    TexImageSource? source
);

TexImageSource的类型为

ImageBitmap
ImageData
HTMLImageElement
HTMLCanvasElement
HTMLVideoElement

答案 1 :(得分:1)

如果您想从类似Uint8Array的数据类型上传数据,则需要使用带有typedArray的texImage2D版本。

那个是

void texImage2D(
    GLenum target,
    GLint level,
    GLint internalformat,
    GLsizei width,
    GLsizei height,
    GLint border,
    GLenum format,
    GLenum type,
    ArrayBufferView? pixels
);

另外你应该知道,像OpenGL这样的WebGL默认将UNPACK_ALIGNMENT设置为4个字节,这意味着每行像素/纹素必须是4个字节的倍数。您可以通过调用

将其更改为1个字节
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);

我之所以提起这件事,是因为您上传了RGB / UNSIGNED_BYTE每个像素3个字节的纹理,这意味着如果您上传2x2像素纹理,每一行都是6个字节。 WebGL会将其填充到8个字节,因此它将需要一个14字节长的缓冲区(第一行只有8个字节,其中只使用前6个字节,最后一行有6个字节。它并不关心最后一行的填充如果你将UNPACK_ALIGNMENT设置为1那么问题就会消失。

顺便说一句,你可以将它应该默认的参数设为1,但WebGL遵循OpenGL,而在OpenGL中默认为4。