mid's site

you're logged in as loser

🌍 Go Paperful

🔗 Subscribe via RSS

Journey into OpenGL: Index Arrays

JiGL

  1. The Series
  2. the First Triangle
  3. the Framebuffer and Depth Buffer
  4. Transformations
  5. Spaces
  6. the Cube?
  7. Vertex Arrays
  8. Index Arrays
  9. ...

Vertices typically appear many times in a single model. By utilizing a so-called index buffer, we can have OpenGL load vertices in a custom order. Furthermore we can have one vertex used in multiple primitives.

The feature does lead to saving space, but there's more to it. An accelerator has a small cache of vertices that have underwent transformation. Reusing them saves time, and this is possible with an index buffer. For this same reason triangle strips are commonly used for older graphics cards.

A half-cube has seven unique vertices. With the generic GL_TRIANGLES mode, we have to send three indices for each triangle. There are three squares in a half-cube, which means 18 indices.

struct Vertex {
	float px, py, pz;
	uint8_t cx, cy, cz;
};

// Setup vertex information
static float hsz = 0.2;
struct Vertex vertices[] = {
	{-hsz, -hsz, -hsz, 255, 0, 0},
	{+hsz, -hsz, -hsz, 0, 255, 0},
	{-hsz, -hsz, +hsz, 0, 255, 0},
	{+hsz, -hsz, +hsz, 0, 0, 255},
	{-hsz, +hsz, -hsz, 0, 255, 0},
	{+hsz, +hsz, -hsz, 0, 0, 255},
	{-hsz, +hsz, +hsz, 0, 0, 255},
};

uint16_t indices[] = {
	// -Y square
	0, 1, 2,
	2, 1, 3,
	// -X square
	0, 2, 4,
	4, 2, 6,
	// -Z square,
	0, 1, 4,
	4, 1, 5,
};

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glVertexPointer(3, GL_FLOAT, sizeof(struct Vertex), &vertices->px);

glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(struct Vertex), &vertices->cx);

// Draw triangles, using 18 indices starting at `indices`.
// Unsigned short is defined as being 16-bit.
glDrawElements(GL_TRIANGLES, 18, GL_UNSIGNED_SHORT, indices);

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

A small tick you may see, is that you cannot get clear, flat colors for each primitive like you can in the previous article, without having to have 18 vertices again. This is because color as an attribute is innate to a vertex. If two vertices have the same position but different colors, then they are technically different vertices.

Flat colors are confined to a niche aesthetic, and texturing, which most games use, doesn't have this problem. Later versions of OpenGL also have their ways of fixing it (the flat qualitifer).

Consider completing the cube again. There is one vertex missing, and 18 indices.