1

I tried to fill a buffer with data before I had called bindBuffer

const triangleBuffer = context.createBuffer();
// context.bindBuffer(context.ARRAY_BUFFER, triangleBuffer);
context.bufferData(context.ARRAY_BUFFER, triangleVertices, context.STATIC_DRAW);

Then I got an error:

WebGL: INVALID_OPERATION: bufferData: no buffer

I created the buffer in the first line and I don't understand why I can't fill it with data.

Can't I just fill created buffer before binding to context.ARRAY_BUFFER? Are there any reasons for this behaviour?

Andrew Lis
  • 37
  • 6

1 Answers1

2

ARRAY_BUFFER is an internal WebGL variable (or rather it's an id for an internal WebGL variable)

It effectively works like this

context = {
  ARRAY_BUFFER: 34962,  // this is an enum value

  arrayBufferBinding: null,

  bindBuffer(target, buffer) {
    if (target === this.ARRAY_BUFFER) {
      this.arrayBufferBinding = buffer;
    }
    ...
  },

  bufferData(target, data, hint) {
    let buffer;
    if (target === this.ARRAY_BUFFER) {
      buffer = this.arrayBufferBinding;
    }
    ...
    setDataOnBuffer(buffer, data, hint);
  },
};

So you have to bind the buffer. WebGL doesn't directly set state on most WebGL objects (buffers, textures, renderbuffers, framebuffers, vertex arrays). You have to bind the object and then refer to it based on where you bound it.

See this and this and this

gman
  • 100,619
  • 31
  • 269
  • 393
  • 1
    Thanks. But I don't understood why does **bindBuffer** require buffer as second argument? Buffer is unused in your example. – Andrew Lis Apr 24 '20 at 09:08
  • sorry, that was a typo. buffer is used now. – gman Apr 24 '20 at 09:18
  • Are there any reasons for why we can't fill buffers with data directly? Or is it just a historical fact? – Andrew Lis Apr 24 '20 at 09:36
  • 2
    You can't fill them directly because whoever designed the API chose to do it that way. There is arguably no reason why the API could not have been `bufferData(buffer, data, hint)` but it's not. Note that OpenGL has direct state access functions, for bufferData it's called [`NamedBufferData`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferData.xhtml). AFAIK it's rare for people to use them just because the indirect way has been the normal since OpenGL shipped.They were only added in OpenGL 4.5 and before that were an optional extension – gman Apr 24 '20 at 09:52
  • 1
    see the linked articles – gman Oct 21 '20 at 17:30