22

Okay,

I am new to 3D graphics and I want to animate individual specific vertices in a model (NOT whole model transforms). My script is largely based off the NEHE webgl tutorial. In this tutorial all object vertices are stored in a buffer, which is initialized once when the program is first run. Here is the initialization code: *Note vertices contains an array of vertices

vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
vertexBuffer.itemSize = 3;
vertexBuffer.numItems = parseInt(vertices.length/vertexBuffer.itemSize);

Now because these are initialized at the start, obviously changing the vertices array will do nothing. So I was wondering how is the best way to modify the vertices in real-time while still keeping it efficient enough to run smoothly.

Is it possible to rebind the buffer somehow eg run this code again at each animation tick?

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

Cheers, J

Josh Mc
  • 9,911
  • 8
  • 53
  • 66

2 Answers2

50

Okay after a whole lot of digging through the net. I have found the following changes must be made; first of all, you must make the vertex array buffer dynamic. this is made possible by using the enumerator 'gl.DYNAMIC_DRAW' where previously in most tutorials we have 'gl.STATIC_DRAW'. Resulting in the following:

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.DYNAMIC_DRAW);

The second change must be triggered in your loop (or tick, or animation) function. A new function is called in order to update the array. You must offcourse first bind the previous dynamic array buffer first:

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

then after this you update the old vertices with the following function:

gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(vertices));

Where the parameters are <buffer_type>, <array_offset>, <new_data>

Source: http://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf

Hope this helps someone :)

J

Josh Mc
  • 9,911
  • 8
  • 53
  • 66
  • This has helped me tremendously! I had the exact same question and you've provided a working solution along with a sensible explanation. Thanks! – Thomas Oct 27 '11 at 11:50
  • Is there a reason this answer and the original question have `bufferData` instead of `gl.bufferData`? I'm assuming typo but since it's carried through maybe I'm missing something. – Grumdrig Sep 16 '12 at 17:38
  • Good spotting, must have copied from the spec. Will update :) – Josh Mc Sep 10 '13 at 00:27
  • You just made my project possible! – Sonofblip Nov 26 '14 at 18:26
4

Alternatively you can follow the steps as explained in http://learningwebgl.com/blog/?p=239.

Here they keep the vertex data constant. Instead they keep changing the matrix mvMatrix which provides for the translations and rotations required. mvMatrix is then fed to the shader via a uniform variable and then multiplied by the vertex position to get the new vertex positions. Hope this helps.