One problem worth mentioning is that the frustum culling algorithm is faulty. The algorithm essentially culls any triangle where all vertices lie outside the frustum. Though this might sound correct, it is very possible to construct any triangle where all vertices lie outside the frustum but the triangle is still partially visible… just imagine really big triangle! This is the exact reason for why it looks like triangles pop out when they reach the edge. One simple way of fixing this would be to make an AABB around each triangle, and make sure the AABB is entirely outside the frustum.