0

I am trying to render a quantity of cubes like in "Minecraft" a chunk with C# + OpenTK + OpenGL 4.1. To do that, I create a buffer with type "ElementArrayBuffer" for indices and a buffer with type "ArrayBuffer" to store the vertices. But I think to describe it, is more difficult than examine the code. If someone has questions please tell me.

So now the problem. The rendering result is not that, what I want and I don't understand why and whats wrong. If I render this I get this result: enter image description here

class Chunk
{
    // The size of the chunk
    // One unit means one cube
    public const int WIDTH = 5;
    public const int HEIGHT = 5;
    public const int DEPTH = 2;

    private int[][][] mData;

    // The attribute location the the shader program
    private int mVePositionLocation;

    private int mVertexArray;
    private int mIndexBuffer;
    private int mVertexBuffer;

    private int mIndexCount;

    public Chunk(int pVePositionLocation)
    {
        mVePositionLocation = pVePositionLocation;

        GenerateData();
        GenerateMesh();
    }

    private void GenerateData()
    {
        mData = new int[DEPTH][][];
        for(int z = 0; z < DEPTH; z++)
        {
            mData[z] = new int[HEIGHT][];
            for(int y = 0; y < HEIGHT; y++)
            {
                mData[z][y] = new int[WIDTH];
                for(int x = 0; x < WIDTH; x++)
                {
                    mData[z][y][x] = 1;
                }
            }
        }


    }
    private void GenerateMesh()
    {
        Queue<float> vertices = new Queue<float>();
        Queue<uint> indices = new Queue<uint>();
        uint offset = 0;

        for (int z = 0; z < DEPTH; z++)
        {
            for (int y = 0; y < HEIGHT; y++)
            {
                for (int x = 0; x < WIDTH; x++)
                {
                    // If the value is bigger than 0 there is a cube so it should be generated
                    if(mData[z][y][x] > 0)
                    {
                        GenerateCube(x, y, z, offset, vertices, indices);

                        // Normally 36 indices offset, but for now I only generate the front face of each cube so only 6 indices
                        offset += 6;
                    }
                }
            }
        }

        // Create and fill the buffer with the indices
        mIndexBuffer = GL.GenBuffer();
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, mIndexBuffer);
        GL.BufferData<uint>(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Count * sizeof(uint)), indices.ToArray(), BufferUsageHint.StaticDraw);

        mVertexArray = GL.GenVertexArray();
        GL.BindVertexArray(mVertexArray);

        // The buffer with the vertices
        mVertexBuffer = GL.GenBuffer();
        GL.BindBuffer(BufferTarget.ArrayBuffer, mVertexBuffer);
        GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Count * sizeof(float)), vertices.ToArray(), BufferUsageHint.StaticDraw);

        // The shader only needs the position
        GL.EnableVertexAttribArray(mVePositionLocation);
        GL.VertexAttribPointer(mVePositionLocation, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0);

        // Store the index count, so I can render later
        mIndexCount = indices.Count;
    }
    private void GenerateCube(int pX, int pY, int pZ, uint pOffset, Queue<float> pVertices, Queue<uint> pIndices)
    {
        // Front face vertices
        pVertices.Enqueue(pX);
        pVertices.Enqueue(pY);
        pVertices.Enqueue(pZ + Cube.DEPTH);

        pVertices.Enqueue(pX + Cube.WIDTH);
        pVertices.Enqueue(pY);
        pVertices.Enqueue(pZ + Cube.DEPTH);

        pVertices.Enqueue(pX);
        pVertices.Enqueue(pY + Cube.HEIGHT);
        pVertices.Enqueue(pZ + Cube.DEPTH);

        pVertices.Enqueue(pX + Cube.WIDTH);
        pVertices.Enqueue(pY + Cube.HEIGHT);
        pVertices.Enqueue(pZ + Cube.DEPTH);

        // Front face indices
        pIndices.Enqueue(pOffset + 0);
        pIndices.Enqueue(pOffset + 2);
        pIndices.Enqueue(pOffset + 3);

        pIndices.Enqueue(pOffset + 0);
        pIndices.Enqueue(pOffset + 3);
        pIndices.Enqueue(pOffset + 1);
    }

    public void Render()
    {
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, mIndexBuffer);
        GL.BindVertexArray(mVertexArray);
        GL.DrawElements(BeginMode.Triangles, mIndexCount, DrawElementsType.UnsignedInt, 0);
    }
}

The shader program:

    string vertexShaderSource = "#version 410\n" +
                                "\n" +
                                "uniform mat4 un_Projection; \n" +
                                "uniform mat4 un_Transform; \n" +
                                "\n" +
                                "layout(location = 0) in vec3 ve_Position;\n" +
                                "\n" +
                                "out vec4 fr_Color;" +
                                "\n" +
                                "void main()\n" +
                                "{\n" +
                                "   fr_Color = vec4(1, 0, 0, 1);\n" +
                                "   gl_Position = un_Projection * un_Transform * vec4(ve_Position.xyz, 1);\n" +
                                "}\n";

    string fragmentShaderSource =   "#version 410\n" +
                                    "\n" +
                                    "in vec4 fr_Color;\n" +
                                    "\n" +
                                    "out vec4 fi_Color;\n" +
                                    "\n" +
                                    "void main()\n" +
                                    "{\n" +
                                    "   fi_Color = fr_Color;\n" +
                                    "}\n";

If someone wants the full project folder: http://www.file-upload.net/download-10301899/Project.zip.html

1 Answers1

0

Ok, I found the mistake. I should not be

// Normally 36 indices offset, but for now I only generate the front face of each cube so only 6 indices
offset += 6;

It should be

// 4 vertices a face so add 4 offset a cube
offset += 4;