Optimizing drawing of cubes

Posted by Christian Frantz on Game Development See other posts from Game Development or by Christian Frantz
Published on 2013-06-24T02:37:09Z Indexed on 2013/06/24 16:39 UTC
Read the original article Hit count: 264

Filed under:
|

After googling for hours I've come to a few conclusions, I need to either rewrite my whole cube class, or figure out how to use hardware instancing. I can draw up to 2500 cubes with little lag, but after that my fps drops. Is there a way I can use my class for hardware instancing? Or would I be better off rewriting my class for optimization?

    public class Cube
{
public GraphicsDevice device;
public VertexBuffer cubeVertexBuffer;

public Cube(GraphicsDevice graphicsDevice)
{
    device = graphicsDevice;

    var vertices = new List<VertexPositionTexture>();

    BuildFace(vertices, new Vector3(0, 0, 0), new Vector3(0, 1, 1));
    BuildFace(vertices, new Vector3(0, 0, 1), new Vector3(1, 1, 1));
    BuildFace(vertices, new Vector3(1, 0, 1), new Vector3(1, 1, 0));
    BuildFace(vertices, new Vector3(1, 0, 0), new Vector3(0, 1, 0));

    BuildFaceHorizontal(vertices, new Vector3(0, 1, 0), new Vector3(1, 1, 1));
    BuildFaceHorizontal(vertices, new Vector3(0, 0, 1), new Vector3(1, 0, 0));

    cubeVertexBuffer = new VertexBuffer(device, VertexPositionTexture.VertexDeclaration, vertices.Count, BufferUsage.WriteOnly);

    cubeVertexBuffer.SetData<VertexPositionTexture>(vertices.ToArray());


}

private void BuildFace(List<VertexPositionTexture> vertices, Vector3 p1, Vector3 p2)
{
    vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 1, 0));
    vertices.Add(BuildVertex(p1.X, p2.Y, p1.Z, 1, 1));
    vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 0, 1));
    vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 0, 1));
    vertices.Add(BuildVertex(p2.X, p1.Y, p2.Z, 0, 0));
    vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 1, 0));
}

private void BuildFaceHorizontal(List<VertexPositionTexture> vertices, Vector3 p1, Vector3 p2)
{
    vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 0, 1));
    vertices.Add(BuildVertex(p2.X, p1.Y, p1.Z, 1, 1));
    vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 1, 0));
    vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 0, 1));
    vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 1, 0));
    vertices.Add(BuildVertex(p1.X, p1.Y, p2.Z, 0, 0));
}

private VertexPositionTexture BuildVertex(float x, float y, float z, float u, float v)
{
    return new VertexPositionTexture(new Vector3(x, y, z), new Vector2(u, v));
}

public void Draw(BasicEffect effect)
{

    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
    {
        pass.Apply();
        device.SetVertexBuffer(cubeVertexBuffer);
        device.DrawPrimitives(PrimitiveType.TriangleList, 0, cubeVertexBuffer.VertexCount / 3);
    }
}
}

The following class is a list that draws the cubes.

    public class DrawableList<T> : DrawableGameComponent
{
    private BasicEffect effect;
    private ThirdPersonCam camera;
    private class Entity
    {
        public Vector3 Position { get; set; }
        public Matrix Orientation { get; set; }
        public Texture2D Texture { get; set; }
    }

    private Cube cube;
    private List<Entity> entities = new List<Entity>();

    public DrawableList(Game game, ThirdPersonCam camera, BasicEffect effect)
        : base(game)
    {
        this.effect = effect;
        cube = new Cube(game.GraphicsDevice);
        this.camera = camera;
    }

    public void Add(Vector3 position, Matrix orientation, Texture2D texture)
    {

        entities.Add(new Entity()
        {
            Position = position,
            Orientation = orientation,
            Texture = texture
        });
    }

    public override void Draw(GameTime gameTime)
    {
        foreach (var item in entities)
        {

            effect.VertexColorEnabled = false;
            effect.TextureEnabled = true;
            effect.Texture = item.Texture;

            Matrix center = Matrix.CreateTranslation(new Vector3(-0.5f, -0.5f, -0.5f));
            Matrix scale = Matrix.CreateScale(1f);
            Matrix translate = Matrix.CreateTranslation(item.Position);

            effect.World = center * scale * translate;
            effect.View = camera.view;
            effect.Projection = camera.proj;

            effect.FogEnabled = true;
            effect.FogColor = Color.CornflowerBlue.ToVector3();
            effect.FogStart = 1.0f;
            effect.FogEnd = 50.0f;

            cube.Draw(effect);
        }

        base.Draw(gameTime);
    }
}
}

There are probably many reasons that my fps is so slow, but I can't seem to figure out how to fix it. I've looked at techcraft as well, but what I have is too specific to what I want the outcome to be to just rewrite everything from scratch

© Game Development or respective owner

Related posts about XNA

Related posts about c#