Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Index buffers in WebGL?

I am trying to learn some WebGL (from this tutorial http://learningwebgl.com/blog/?page_id=1217). I followed the guide, and now I am trying to implement my own demo. I want to create a graphics object that contains buffers and data for each individual object to appear in the scene. Currently, I have a position vertex buffer, a texture coordinate buffer, and a normals buffer. In the tutorial, he uses another buffer, an index buffer, but only for cubes. What is the index buffer actually for? Should I implement it, and is it useful for anything other than cubes?

like image 311
Sefu Avatar asked Dec 23 '12 07:12

Sefu


People also ask

What is index buffer?

Index buffers, represented by the IDirect3DIndexBuffer9 interface, are memory buffers that contain index data. Index data, or indices, are integer offsets into vertex buffers and are used to render primitives using the IDirect3DDevice9::DrawIndexedPrimitive method.

How do buffers work in Webgl?

A buffer object is a contiguous block of memory in the GPU that can be accessed very quickly by shader programs executing on the GPU. Buffer objects store the data that shader programs need for rendering. The contents of a buffer object is always an 1-dimensional array.

What is a vertex index?

A vertex buffer can be thought of as an array of vertices, so the VB Index is simply the index into the vertex buffer for the target vertex. Similarly, an IB Index is an index into the index buffer.

What are OpenGL indices?

Indices is defined as a GLubyte array of 48 elements; GLubyte is the OpenGL data type for an unsigned byte ( unsigned char ). You could use any of the following unsigned integral OpenGL data types: GLubyte , GLushort , and GLuint , since indices are never negative (signed) or fractional (float/double).


2 Answers

Vertices of your objects are defined by positions in 3D coordinate system (euclidian coordinate system). So you can take every two following vertices and connect them with line right after your 3D coordinate systems is projected to 2D raster (screen or some target image) by rasterization process. You'll get so called wireframe.

cube wireframe

The problem of wireframe is that it's not definite. If you look to the wireframe cube at particular angles, you cannot say, how is the cube exactly rotated. That's because you need to use visibility algorithms to determine, which part of the cube is closer to the observers position (position of camera).

But lines itself cannot define surface, which is necessary to determine which side of the cube is closer to observer that others. The best way how to define surfaces in computer graphics are polygons, exactly the triangle (it have lots of cons for computer graphics).

So you have cube now defined by triangles (so call triangle mesh).

cube triangle mesh

But how to define which vertices forms triangle? By the index buffer. It contains index to the vertex buffer (list with your vertices) and tells the rasterizing algorithm which three vertices forms triangle. There are lot of ways, how to interpret indexes in index buffer to reduce repetition of same vertices (one vertex might be part of lot of triangles), you may find some at article about graphics primitives.

like image 185
Sorceror Avatar answered Sep 28 '22 08:09

Sorceror


Technically you don't need an index buffer. There are two ways to render geometry, with glDrawArrays and glDrawElements. glDrawArrays doesn't use the index buffer. You just write the vertices one after the other into the buffers and then tell GL what to do with the elements. If you use GL_TRIANGLES as mode in the call, you have to put triples of data (vertices, normals, ...) into the buffers, so when a vertex is used multiple times you have to add it mutliple times to the buffers.

glDrawElements on the contrary can be used to store a vertex once and then use it multiple times. There is one catch though, the set of parameters for a single index is fixed, so when you have a vertex, where you need two different normals (or another attribute like texture coordinates or colors) you have to store it for each set of properties.

For spheres glDrawElements makes a lot of sense, as there the parameters match, but for a cube the normals are different, the front face needs a different normal than the top face, but the position of the two vertices is the same. You still have to put the position into the buffer twice. For that case glDrawArrays can make sense.

It depends on the data, which of calls needs less data, but glDrawElements is more flexible (as you can always simulate glDrawArrays with an index buffer which contains the numbers 0, 1,2, 3, 4, ...).

like image 24
Josef Meixner Avatar answered Sep 28 '22 08:09

Josef Meixner