Warning: nerd talk ahead. Stop reading if you don’t care about the nerdy details.
It turns out that I can’t de-dupe the points as I thought I could. The same points in 3D space are used multiple times (for example, the vertex where two or more triangles meet), but each has unique attributes that can’t be de-duplicated. On the GPU, those values are embedded in the point array. Specifically, the problem I ran into was the normal vector for the point, which is used to determine lighting. That value is different for each triangle, despite the points being the same. Sharing normals across faces results in some truly bad lighting quirks.
It also turns out that C++ will silently convert a point tuple to a triangle tuple.
typedef std::tuple<float, float, float> Point_t; typedef std::tuple<int, int, int> Triangle_t;
Points are locations in 3D space. Triangles reference the indexes of three different points. If you accidentally construct a point using Triangle_t instead of a Point_t, it will just quietly truncate your floating point values down to integers. And you’ll end up with really weird shapes.