It turns out that the worst of your problems are in PrimitiveShape.Draw and not in the prism generation code:
- you have indices but you use GraphicsDevice.DrawPrimitives instead of GraphicsDevice.DrawIndexedPrimtives
- you have a GetSizeInBytes abstract method which is implemented correctly in the Prism3D class but you don't use it in Draw
Corrected code for Draw:
vertexBuffer = new VertexBuffer(graphicsDevice, GetSizeInBytes() * vertices.Count, BufferUsage.WriteOnly);
vertexBuffer.SetData(vertices.ToArray());
indexBuffer = new IndexBuffer(graphicsDevice, typeof(int), indices.Count, BufferUsage.WriteOnly);
indexBuffer.SetData(indices.ToArray());
graphicsDevice.Indices = indexBuffer;
graphicsDevice.Vertices[0].SetSource(vertexBuffer, 0, GetSizeInBytes());
graphicsDevice.VertexDeclaration = new VertexDeclaration(graphicsDevice, GetVertexElements());
graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices.Count, 0, triangles);
And as I suspected the prism code has trouble with the indices. For simplicity I'd use only one for loop like this:
int baseTopIndex = 1;
int baseBottomIndex = topVertices.Length + 2;
for (int i = 0; i < topVertices.Length; i++)
{
int j = (i + 1) % topVertices.Length;
// top face triangle
Indices.Add(baseTopIndex + i);
Indices.Add(baseTopIndex - 1);
Indices.Add(baseTopIndex + j);
// bottom face triangle
Indices.Add(baseBottomIndex + i);
Indices.Add(baseBottomIndex - 1);
Indices.Add(baseBottomIndex + j);
// side triangle 1
Indices.Add(baseTopIndex + i);
Indices.Add(baseTopIndex + j);
Indices.Add(baseBottomIndex + j);
// side triangle 2
Indices.Add(baseTopIndex + i);
Indices.Add(baseBottomIndex + j);
Indices.Add(baseBottomIndex + i);
}
Of course you can still have 4 for loops if you want but pay attention to the way you deal with the last edge, you got it wrong in all your for loops.