2
\$\begingroup\$

I'm drawing a simple Voxel world. When I naively render all the vertices, things look fine. But when I change my code to include a ViewFrustum check, I start getting strange visual glitches like this:

glitch http://www.phillipwei.com/game/glitch.png

The large square block is meant to be there; the strange triangles on the bottom left are not. These glitches appear all over the screen, and intermittently appear/vanish as I move my camera around. The draw code looks something like this:

basicEffect.World = Matrix.Identity;
basicEffect.View = Matrix.CreateLookAt(
    camera.Position,
    camera.Position + camera.GetForward(), 
    camera.GetUp()
);
basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(
    camera.FieldOfView, 
    camera.AspectRatio, 
    1.0f, 
    1000.0f
);

BoundingFrustum viewFrustum = new BoundingFrustum(basicEffect.View * basicEffect.Projection);

List<VertexPositionTexture> vertices = new List<VertexPositionTexture>();
foreach (Voxel voxel in voxelWorld.GetAllVoxels())
{
    if (viewFrustum.Intersects(voxel.Cube.BoundingBox))
    {
        vertices.AddRange(voxel.Cube.GetVertices());
    }
}

if (vertices.Count != 0)
{
    foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
    {
        pass.Apply();
        using (VertexBuffer buffer = new VertexBuffer(
            graphicsDevice,
            VertexPositionTexture.VertexDeclaration,
            vertices.Count,
            BufferUsage.WriteOnly))
        {
            buffer.SetData(vertices.ToArray());
            graphicsDevice.SetVertexBuffer(buffer);
        }
        graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, vertices.Count);
    }
}

So if I remove the viewFrustum.Intersects() check everything is fine. It seems unlikely to me that the viewFrustum check itself is causing the error, but I can't figure out where the problem is coming from. Any suggestions?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Not related to your Q, but: BoundingFrustum, List, & VertexBuffer are classes, not a structs. Creating a new one each frame is going to create garbage which can affect CPU performance. As for the Q, Have you tried either a DynamicVertexBuffer that you update each frame (instead of a new regular VertexBuffer - or - DrawUserPrimitives() and just send a list of Vector3 triangle positions to the device each frame? \$\endgroup\$
    – Steve H
    Feb 6, 2012 at 21:30
  • 2
    \$\begingroup\$ Shouldn't DrawPrimitives take the triangle count, not the vertex count? \$\endgroup\$
    – Blecki
    Feb 7, 2012 at 0:56
  • \$\begingroup\$ @Blecki has your answer (why not turn it into a real answer?). 'primitiveCount' refers to the primitive type you are using (e.g. TriangleList: divide vertex count by 3, TriangleStrip: subtract 2 from vertex count and so forth). Those artifacts are arising due to uninitialized memory and will be different across application executions (or machine reboots). \$\endgroup\$ Feb 7, 2012 at 22:33
  • \$\begingroup\$ @Blecki Thanks! I think this is it. If you post that as the answer I can give you some kudos. \$\endgroup\$
    – phillipwei
    Feb 11, 2012 at 14:50
  • \$\begingroup\$ @SteveH Good points. I'm aware of the general performance concerns (I rearranged some code to try and make the question more concise) though I hadn't heard of DynamicVertexBuffers -- will incorporate that. \$\endgroup\$
    – phillipwei
    Feb 11, 2012 at 14:52

1 Answer 1

2
\$\begingroup\$

DrawPrimitives takes the triangle count, not the vertex count. You should pass verticies.Count / 3.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .