Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm currently following this guide to render my scene to a texture to generate a depth / shadow map: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/

The guide is in C++. I'm converting it into WebGL - JavaScript and so far have been successful, but unfortunately come across this blunder in Chrome:

WebGL: INVALID_OPERATION: texImage2D: ArrayBufferView not big enough for request

This is an error relating to:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1024, 768, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 0]));

When the width and height of 1024 to 768 are set to 1, it does not produce an error.

In the guide, it uses the following:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 768, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

There is a great answer to a similar question here: Error when creating textures in WebGL with the RGB format which leads me to believe that since the texture is non-existent at the time of calling the method, it can not be bigger than 1 pixel, but I'm unsure if this is correct? EDIT: Not a duplicate of this question for 2 reasons. 1, I would not have asked this question if it was a duplicate and 2, the answer explains why it is not a duplicate.

The rest of the converted code from the guide I'll dump below:

// shadow test
this.frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);
this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1024, 768, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 0]));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
this.depthBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, this.depthBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1024, 768);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.depthBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT0_EXT]);
gl.bindFramebuffer(gl.FRAMEBUFFER, this.buffer);
gl.viewport(0, 0, 1024, 768);

I've tagged this with C++ and OpenGL for help in understanding the differences with this method between WebGL - JavaScript and OpenGL - C++.

Use a WebGL guide instead of an OpenGL guide? BTW this is really the same in OpenGL and WebGL. The difference is WebGL catches the error, OpenGL just reads past the end of the buffer you supply causing both a potential security issue as well as a possible crash. In other words your WebGL code is equivalent to something like in C gl.texImage2D(....., 1024, 768, ...., calloc(4, 1)); This would allocate 4 bytes, pass a pointer to it to OpenGL, and tell OpenGL to read 3145728 bytes from the memory where those 4 bytes you allocated are. – gman Jan 20, 2019 at 14:22

The error you're getting has nothing to do with unpack alignment but the fact that you simply can not fill a 1024x768 texture with just 4 bytes. texImage2D requires you to either provide null(in which case a buffer the size of the texture is initialized, zero filled and used to initialize the texture) or a buffer the size of the texture which in your case would be 1024 * 768 * 3 bytes which coincidentally is a multiple of 4(so you would not run into any unpacking issues).

Here's the relevant excerpt of the WebGL 1 specification:

If pixels is null, a buffer of sufficient size initialized to 0 is passed. [...] If pixels is non-null but its size is less than what is required by the specified width, height, format, type, and pixel storage parameters, generates an INVALID_OPERATION error.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.