简体   繁体   中英

(WebGL) How to add vertices to an already initialized vertex buffer?

I am following WebGL tutorials. I have an initialized vertex buffer with buffer data's purpose is set to gl.STATIC_DRAW . As far as I have read from the MDN's documentation which describes usage , gl.STATIC_DRAW is used if my vertex data is not change throughout the application. As they state:

The contents are intended to be specified once by the application, and used many times as the source for WebGL drawing and image specification commands.

I currently have this piece of code to initialize my vertex buffer:

const vertices = new Float32Array([
  -1.0, 1.0,   -1.0, -1.0,   1.0, 1.0,   1.0, -1.0
]);
const n = 4;

const vertexBuffer = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

const aPosition = gl.getAttribLocation(program, 'aPosition');

gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aPosition);

I want to alter the content of this buffer, for example add new vertex coordinates to be drawn. I don't want to re-initialize the whole vertex buffer as it would be, I assume, wouldn't be good in performance wise.

I have the idea of using the usage as gl.DYNAMIC_DRAW , as they state in the MDN documentation:

The contents are intended to be respecified repeatedly by the application, and used many times as the source for WebGL drawing and image specification commands.

But if I use this value as my usage, how will I provide new vertices to the current buffer and redraw? I couldn't find any example that shows this.

Thank you in advance.

You have 2 options

  1. call gl.bufferData and pass it your new data

    This reallocates the buffer and copies your data in

  2. call gl.bufferSubData this lets you copy data to a portion of the buffer.

    In this case you would first call gl.bufferData to allocate the buffer then gl.bufferSubData to update data. If you want to use more or less data you'd deal with that by passing a different count to gl.drawArrays , use different indices with gl.drawElements etc...

    Example:

     const maxSizeInBytes = 100; const buf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buf); // allocate a buffer with 100 bytes gl.bufferData(gl.ARRAY_BUFFER, maxSizeInBytes, gl.DYNAMIC_DRAW); 

    then later

     gl.bindBuffer(gl.ARRAY_BUFFER, buf); const data = new Float32Array([123, 456, 789]); const offsetInBytes = 20; // update bytes 20 to 31 of the buffer gl.bufferSubData(gl.ARRAY_BUFFER, offsetInBytes, data); 

note that the value at the end of gl.bufferData is a hint . The driver may or may not do anything useful with that hint.

Let me also add, the most common use case is that buffer data never gets updated. Rather you make a different buffer or buffers for each thing you want to draw, "tree", "house", "person", "triangle", "square", "circle", "star" and then switch buffers to draw different things.

I'm not saying you shouldn't change the contents of a buffer. It's just you said you're new to WebGL so I thought I'd pass on that most apps don't much change the contents of buffers and even those that do it's often the exception for the majority of things they draw.

PS: you might find these tutorials helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM