Assuming you're storing your buffers on the GPU and not in client memory, an index buffer won't do anything to reduce bandwidth to the GPU after initialization. It instead saves VRAM space by not having to duplicate vertex data.
If your data is set up in such a way that no vertices ever repeat, using indices is redundant and won't save space.
In general you should be thinking of a vertex as a set of unique positions, texture coordinates, and normals. If two vertices have the same position, but different texture coordinates and normals, they are not the same vertex and should not be treated as such.
Typically when dealing with 3d models that consist of thousands of vertices, there will be a lot of vertex overlap and using indices will help a lot. It's a bit interesting that you don't have that many duplicated vertices.
Here are two examples of where indexing is useful and where it is not:
Example 1
You are drawing a square as two separate triangles.
v0---v3
|\ |
| \ |
| \|
v1---v2
Since this example is in 2d, we can only really use positions and texture coordinates. Without indexing, your vertex buffer will look like this if you interleave the positions and texture coordinates together:
p0x, p0y, t0x, t0y,
p1x, p1y, t1x, t1y,
p2x, p2y, t2x, t2y,
p0x, p0y, t0x, t0y,
p2x, p2y, t2x, t2y,
p3x, p3y, t3x, t3y
When you use indices, your vertex buffer will look like this:
p0x, p0y, t0x, t0y,
p1x, p1y, t1x, t1y,
p2x, p2y, t2x, t2y,
p3x, p3y, t3x, t3y
and you'll have an index buffer that looks like this:
0, 1, 2,
0, 2, 3
Assuming your vertex data is all float
s and your indices are byte
s, the amount of space taken unindexed is 96 bytes, and indexed is 70 bytes.
It's not a lot, but this is just for a single square. Yes, this example isn't the most optimized way of drawing a square (you can avoid indices in the second example by drawing as triangle strips and not triangles), but it's the simplest example I can come up with.
Typically with more complicated models, you'll either be indexing vertices together for really long triangle strips or triangles and the memory savings become huge.
Example 2
You're drawing a circle as a triangle fan. If you don't know how triangle fans work, here's a pretty good image that explains it. The vertices in this case are defined alphabetically A-F.
Image from the Wikipedia article for Triangle fan.
To draw a circle using this method, you would start at any vertex and add all the other vertices in order going either clockwise or counter-clockwise. (You might be able to better visualize it by imagining A
moved down to be below F
and B
in the above diagram) It works out so that the indices are sequential and never repeat.
In this case, adding an index buffer will be redundant and take up more space than the unindexed version. The index buffer would look something like:
0, 1, 2, 3, 4, ..., n
The unindexed version would be the exact same, just without the index buffer.
In 3d, you'll find it far less common to be able to find a drawing mode that matches your indexing completely, as seen in the circle example. In 3d, indexing is almost always useful to some degree.