10
$\begingroup$

I have a vertex buffer like this:

0.0, 0.0,
1.0, 0.0,
0.0, 0.6,
1.0, 0.6,
0.5, 1.0

I have the following index buffer:

0, 2,
2, 4,
4, 3,
3, 2,
2, 1,
1, 0,
0, 3,
3, 1

I know I want to draw gl.LINES using WebGL, means multiple seperated line segments.

gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, indexBuffer);

It seems to enable drawing of multiple line segments in a single draw call in WebGL.

Could someone ELI5 to me, what is an index buffer and how is it related to vertex buffers? How to generate index buffers from my primitives?

$\endgroup$
11
$\begingroup$

Could someone ELI5 to me, what is an index buffer and how is it related to vertex buffers

Your vertex buffer contains the X and Y coordinates of 5 vertices. They are:

index |  X  |  Y
  0   | 0.0 | 0.0 
  1   | 1.0 | 0.0
  2   | 0.0 | 0.6
  3   | 1.0 | 0.6
  4   | 0.5 | 1.0

Your index buffer contains information about which lines to draw between these vertices. It uses the index of each vertex in the vertex buffer as a value.

Since you are drawing lines, each pair of consecutive values in your index buffer indicate a line segment. For example, if the index buffer starts with 0, 2, it means draw a line between the 0th and 2nd vertices in the vertex array, which in this case would draw a line going from [0.0, 0.0] to [0.0, 0.6].

In the following graphic each pair of indices is color coordinated with the line it indicates:

enter image description here

Similarly, if you were drawing triangles instead of lines, you would need to supply an index buffer where each 3 consecutive values indicate the indices of three vertices in the vertex buffer, e.g.

0, 1, 2,
2, 1, 3,
2, 3, 4,
$\endgroup$
5
$\begingroup$

If you have a vertex buffer like this:

var vertices = [
  0.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.5, 1.0, 0.0
]

And simply draw it as it is:

// Create an empty buffer object
var vertex_buffer = gl.createBuffer();

// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 5);

It would require two dedicated coordinates for each line segment. With the vertices as defined above, it would only be possible two draw two lines:

two lines

If you have the following indices defined:

var indices = [
  0, 2,
  2, 4,
  4, 3,
  3, 2,
  2, 1,
  1, 0,
  0, 3,
  3, 1
]

It is possible to draw lines which intersect the same vertices again and again. This reduces redundancy. If you bind the index buffer and tell the GPU to draw line segments connecting the vertices by the order specified in the indecies array:

var index_buffer = gl.createBuffer();

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

// draw geometry lines by indices
gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, index_buffer);

One can draw complexer figures without redefining the same vertices over and over again. This is the result:

a house

To achieve the same result without indices, the vertex buffer should look like the following:

var vertices = [
  0.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.5, 1.0, 0.0,
  0.5, 1.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.0, 0.0
]

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 16);

Which results in the same image:

yet another house

Note the huge redundancy in stored vertices.

$\endgroup$
  • 2
    $\begingroup$ If you plan to immediately answer your own question please at least mention it in the question so others don't waste their time. $\endgroup$ – Rotem Apr 13 '16 at 12:50
  • 2
    $\begingroup$ Every good question should have 2 or 3 good answers. You did not waste your time and I really appreciated your effords. I need this thread to explain the logic to a project partner and your post will help him alot. $\endgroup$ – Waqar Lim Apr 13 '16 at 12:53
  • 1
    $\begingroup$ @5chdn Self answering is highly encouraged. Thanks for adding this answer. If you have an answer in mind at the time you post a question, there is a tick box below the question which will allow you to write your answer before posting the question, so both will appear at the same time. This is just to let you know in case it is useful - you certainly don't need to do this and self answers are still very welcome at any interval of time after posting the question. $\endgroup$ – trichoplax Apr 16 '16 at 9:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.