-1
\$\begingroup\$

I'm having a pretty strange problem that I didn't think I'd run into. I was able to store a 50x50 grid in one vertex buffer finally, in hopes of better performance. Before I had each cube have an individual vertex buffer and with 4 50x50 grids, this slowed down my game tremendously. But it still ran. With 4 50x50 grids with my new code, that's only 4 vertex buffers. With the 4 vertex buffers, I get a memory error. When I load the game with 1 grid, it takes forever to load and with my previous version, it started up right away. So I don't know if I'm storing chunks wrong or what but it stumped me -.-

Thats how theyre stored. The array I'm reading from is a byte array which defines the coordinates of my map. Now with my old version, I used the same loading from an array so that hasn't changed. The only difference is the one vertex buffer instead of 2500 for a 50x50 grid. cubes is just a normal list that holds all my cubes for the vertex buffer.

Another thing that just came to mind would be my draw calls. If I'm setting an effect for each cube in my cube list, that's probably going to take a lot of memory. How can I avoid doing this? I need the foreach method to set my cubes to the right position

As requested, here's my entire cube class plus the draw method within my main class

    public class Cube
{
    BasicEffect effect;
    Texture2D grass;
    Texture2D texture;

    public GraphicsDevice device;

    VertexBuffer vertexBuffer;
    IndexBuffer indexBuffer;

    List<VertexPositionTexture> vertices = new List<VertexPositionTexture>();
    List<short> indices = new List<short>();

    public Vector3 cubePosition { get; set; }

    public List<Cube> cubes = new List<Cube>();

    public int no;

    public Cube(GraphicsDevice graphicsDevice, Vector3 Position, Texture2D Texture)
    {
        device = graphicsDevice;
        Texture = grass ;
        cubePosition = Position;

        effect = new BasicEffect(device);
    }

    public void Draw(BasicEffect effect)
    {
        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        {
            no++;
            pass.Apply();
            device.SetVertexBuffer(vertexBuffer);
            device.Indices = indexBuffer;
            device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 8, 0, 12);
        }
    }


    private void SetUpIndices()
    {
        //Front face
        //bottom right triangle
        indices.Add(0);
        indices.Add(2);
        indices.Add(3);

        indices.Add(0);
        indices.Add(1);
        indices.Add(2);

        indices.Add(1);
        indices.Add(5);
        indices.Add(6);

        indices.Add(1);
        indices.Add(6);
        indices.Add(2);

        indices.Add(2);
        indices.Add(6);
        indices.Add(7);

        indices.Add(2);
        indices.Add(7);
        indices.Add(3);

        indices.Add(4);
        indices.Add(7);
        indices.Add(6);

        indices.Add(4);
        indices.Add(6);
        indices.Add(5);

        indices.Add(1);
        indices.Add(4);
        indices.Add(5);

        indices.Add(1);
        indices.Add(0);
        indices.Add(4);

        indices.Add(0);
        indices.Add(7);
        indices.Add(4);

        indices.Add(0);
        indices.Add(3);
        indices.Add(7);
        #region IndicesArray
        /*indicesArray[0] = 0;
        indices[1] = 2;
        indices[2] = 3;
        //top left triangle
        indices[3] = 0;
        indices[4] = 1;
        indices[5] = 2;
        //back face
        //bottom right triangle
        indices[6] = 1;
        indices[7] = 5;
        indices[8] = 6;
        //top left triangle
        indices[9] = 1;
        indices[10] = 6;
        indices[11] = 2;
        //Top face
        //bottom right triangle
        indices[12] = 2;
        indices[13] = 6;
        indices[14] = 7;
        //top left triangle
        indices[15] = 2;
        indices[16] = 7;
        indices[17] = 3;
        //bottom face
        //bottom right triangle
        indices[18] = 4;
        indices[19] = 7;
        indices[20] = 6;
        //top left triangle
        indices[21] = 4;
        indices[22] = 6;
        indices[23] = 5;
        //left face
        //bottom right triangle
        indices[24] = 1;
        indices[25] = 4;
        indices[26] = 5;
        //top left triangle
        indices[27] = 1;
        indices[28] = 0;
        indices[29] = 4;
        //right face
        //bottom right triangle
        indices[30] = 0;
        indices[31] = 7;
        indices[32] = 4;
        //top left triangle
        indices[33] = 0;
        indices[34] = 3;
        indices[35] = 7;
        */
        #endregion IndicesArray

    }



    private void SetUpVertices()
    {
        #region VPNormalTexture
        /*
        //front left bottom corner
        vertices.Add(new VertexPositionNormalTexture(new Vector3(0, 0, 0), new Vector3(0, 0, 0), new Vector2(1, 0)));
        //front left upper corner
        vertices.Add(new VertexPositionNormalTexture(new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector2(0, 0)));
        //front right upper corner
        vertices.Add(new VertexPositionNormalTexture(new Vector3(1, 1, 0), new Vector3(1, 1, 0), new Vector2(0, 1)));
        //front lower right corner
        vertices.Add(new VertexPositionNormalTexture(new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector2(1, 1)));
        //back left lower corner
        vertices.Add(new VertexPositionNormalTexture(new Vector3(0, 0, -1), new Vector3(0, 0, -1), new Vector2(1, 0)));
        //back left upper corner
        vertices.Add(new VertexPositionNormalTexture(new Vector3(0, 1, -1), new Vector3(0, 1, -1), new Vector2(0, 0)));
        //back right upper corner
        vertices.Add(new VertexPositionNormalTexture(new Vector3(1, 1, -1), new Vector3(1, 1, -1), new Vector2(0, 1)));
        //back right lower corner
        vertices.Add(new VertexPositionNormalTexture(new Vector3(1, 0, -1), new Vector3(1, 0, -1), new Vector2(1, 1)));
        */
        #endregion VPNormalTexture
        //front left bottom corner
        vertices.Add(new VertexPositionTexture(new Vector3(0, 0, 0), new Vector2(1, 0)));
        //front left upper corner
        vertices.Add(new VertexPositionTexture(new Vector3(0, 1, 0), new Vector2(0, 0)));
        //front right upper corner
        vertices.Add(new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(0, 1)));
        //front lower right corner
        vertices.Add(new VertexPositionTexture(new Vector3(1, 0, 0), new Vector2(1, 1)));
        //back left lower corner
        vertices.Add(new VertexPositionTexture(new Vector3(0, 0, -1), new Vector2(1, 0)));
        //back left upper corner
        vertices.Add(new VertexPositionTexture(new Vector3(0, 1, -1), new Vector2(0, 0)));
        //back right upper corner
        vertices.Add(new VertexPositionTexture(new Vector3(1, 1, -1), new Vector2(0, 1)));
        //back right lower corner
        vertices.Add(new VertexPositionTexture(new Vector3(1, 0, -1), new Vector2(1, 1)));
        #region VPColor
        /*
        //front left bottom corner
        vertices.Add(new VertexPositionColor(new Vector3(0, 0, 0), color));
        //front left upper corner
        vertices.Add(new VertexPositionColor(new Vector3(0, 1, 0), color));
        //front right upper corner
        vertices.Add(new VertexPositionColor(new Vector3(1, 1, 0), color));
        //front lower right corner
        vertices.Add(new VertexPositionColor(new Vector3(1, 0, 0), color));
        //back left lower corner
        vertices.Add(new VertexPositionColor(new Vector3(0, 0, -1), color));
        //back left upper corner
        vertices.Add(new VertexPositionColor(new Vector3(0, 1, -1), color));
        //back right upper corner
        vertices.Add(new VertexPositionColor(new Vector3(1, 1, -1), color));
        //back right lower corner
        vertices.Add(new VertexPositionColor(new Vector3(1, 0, -1), color)); 
        * */
        #endregion VPColor
    }

    public void CreateMap()
    {

        byte[,] map = 
        {
            //imagine a 2d array with 50 rows and columns of zeros. too big to post

        };

        for (int x = 0; x < 50; x++)
        {
            for (int z = 0; z < 50; z++)
            {
                for (int y = 0; y <= map[x, z]; y++)
                {
                    SetUpVertices();
                    SetUpIndices();
                    cubes.Add(new Cube(device, new Vector3(x, map[x, z] - y, z), grass));
                }
            }
        }

        vertexBuffer = new VertexBuffer(device, typeof(VertexPositionTexture), vertices.Count(), BufferUsage.WriteOnly);
        vertexBuffer.SetData<VertexPositionTexture>(vertices.ToArray());

        indexBuffer = new IndexBuffer(device, typeof(short), indices.Count(), BufferUsage.WriteOnly);
        indexBuffer.SetData(indices.ToArray());
    }


    public void LoadContent(ContentManager content)
    {
        grass = content.Load<Texture2D>("grass");
    }
}

}

    public void DrawMap(GameTime gameTime)
    {

        foreach (Cube block in cube.cubes)
        {

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

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

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

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

            cube.Draw(effect);
            noc++;
        }
\$\endgroup\$
  • \$\begingroup\$ Seems more like a general programming question to me. \$\endgroup\$ – Tim Holt Jul 1 '13 at 6:53
  • \$\begingroup\$ @TimHolt Very much not the case. \$\endgroup\$ – Andrew Russell Jul 1 '13 at 9:32
  • \$\begingroup\$ @Christian: Maybe post the code for Cube so we can all be on the same page here. Especially its data, and the methods you're using (Draw() and the constructor). \$\endgroup\$ – Andrew Russell Jul 1 '13 at 9:37
1
\$\begingroup\$

I used my eyes this time and looked at the line that gave me the error. I was creating an effect every time I created a new cube. I don't really need 100,000 instances of basic effect so I deleted that line from my constructor and it worked

     effect = new BasicEffect();

Now that the game runs fine, I'm getting an incredibly low frame rate. But that is for another question.

\$\endgroup\$
0
\$\begingroup\$

Use just one vertex buffer and draw it many times to save memory. Take advantage of hardware instancing to increase performance.

\$\endgroup\$
  • \$\begingroup\$ I tried that before with single cubes. I couldn't get a 50x50 without fps drop \$\endgroup\$ – Christian Frantz Jul 1 '13 at 7:10
  • \$\begingroup\$ I believe you must lose fps because of the sheer number of cubes in any implementation, with that said perhaps you can benefit from a compromise like 10x10x25. Are you truly out of memory? And have you experimented with shaders, maybe raytracing in the fragment shader is acceptable? \$\endgroup\$ – MickLH Jul 1 '13 at 7:20
  • \$\begingroup\$ My full map is going to be 1000x1000, defined by me. So there's no randomization going on. If the grid is only 10x10, I'll need 1000 user defined vertex buffers, which will take a while to code. But at this point I'm willing to do anything to get this thing working right. I haven't tried anything with shaders tho. \$\endgroup\$ – Christian Frantz Jul 1 '13 at 7:26
  • \$\begingroup\$ Wow you should have some kind of tool for defining your data my friend, that sounds quite painful. I still think a shader-enhanced batch approach will serve you. \$\endgroup\$ – MickLH Jul 1 '13 at 15:22
  • \$\begingroup\$ Yeah that's why I'm planning on using 50x50 size chunks or even bigger if I can manage. I don't mind hardcoding 200 vertex buffers. I just need it to work. Can you explain shader-enhanced batching or point me to a tutorial? \$\endgroup\$ – Christian Frantz Jul 1 '13 at 18:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.