updateTextureData does not work correctly for CubeTextures

When calling updateTextureData targeting a CubeTexture’s face, there are WebGL errors such as

  • WebGL: INVALID_ENUM: bindTexture: invalid target
  • WebGL: INVALID_OPERATION: texSubImage2D: no texture bound to target

and inconsistent behavior.

See this playground: https://playground.babylonjs.com/#UDXQLH#2

It creates a RawCubeTexture, then attempts to set the texture data for each face as the images are downloaded. Occasionally, some faces are not updated and there are errors in the console.

The problem is these lines I believe (Sorry I can only add two links!)
thinEngine.ts L4626
thinEngine.ts L4634

_bindTextureDirectly should take gl.TEXTURE_CUBE_MAP as the target, not gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex

Here is a playground making the calls directly and working correctly: https://playground.babylonjs.com/#30A01T#4

1 Like

Welcome aboard!

Thanks for the report, this PR will fix the problems:

Once this PR is merged, you will also be able to simply pass null for the data parameter instead of dummy buffers.

2 Likes

Thanks for the quick work!

Once this PR is merged, you will also be able to simply pass null for the data parameter instead of dummy buffers.

I tried this out and it seems like the texture pixels get initialized to 0, which is great, but I wonder if this behavior is reliable across browsers? I didn’t see anything specific about a null pixels parameter in the texImage2d API reference.

Not passing data to texImage2D is supported as you can see in MDN:

The first overload does not take the pixels parameter, so does not initialize the texture with data. In the code I pass null because the definition file provided by VSCode (lib.dom.d.ts) describes the first two overloads by:

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

However, MDN says nothing about the initial content, so I don’t think you can rely on the texture being initialized to 0 (I think you will need to look at the WebGL specification to have a definitive answer).

[…] Ok, here’s the answer from the spec:

Ah, good to see some confirmation, thanks! I was also looking at the MDN reference.