0

I have a Cube mesh defined like this:

public GameObject CreateCube(Vector3 size, Vector3 position)
        {
            GameObject result = App.CreateGameObject("Cube");
            Mesh m = result.AddComponent<Mesh>(new Mesh());
            size /= 2;
            float[] vertices = new float[] {
                position.X - size.X, position.Y - size.Y, position.Z - size.Z, 1.0f,1.0f,1.0f, //0
                position.X + size.X, position.Y - size.Y, position.Z - size.Z, 0.0f,1.0f,1.0f, //1
                position.X - size.X, position.Y + size.Y, position.Z - size.Z, 1.0f,0.0f,1.0f, //2
                position.X + size.X, position.Y + size.Y, position.Z - size.Z, 1.0f,1.0f,0.0f, //3
                position.X - size.X, position.Y - size.Y, position.Z + size.Z, 0.0f,0.0f,1.0f, //4
                position.X + size.X, position.Y - size.Y, position.Z + size.Z, 1.0f,0.0f,0.0f, //5
                position.X - size.X, position.Y + size.Y, position.Z + size.Z, 0.0f,1.0f,0.0f, //6
                position.X + size.X, position.Y + size.Y, position.Z + size.Z, 1.0f,1.0f,1.0f  //7
            };
            m.SetVertices(vertices);
            uint[] indices = new uint[] {
                0,2,1,1,2,3, //front
                6,4,7,7,4,5, //back
                2,6,3,3,6,7, //top
                4,0,5,5,0,1, //bottom
                0,4,2,2,4,6, //left
                5,1,7,7,1,3,1 //right
            };
            m.SetIndices(indices);
            MeshRenderer r = result.AddComponent<MeshRenderer>(new MeshRenderer());
            r.PrimitiveType = PrimitiveType.Triangles;
            r.Shader = App.Shaders["default"];

            r.SetDrawHints(new VertexObjectDrawHint("pos",3,6,0), new VertexObjectDrawHint("color", 3, 6, 3));
            return result;
        }

Now you can see I added a "1" at the end of the indices. I had to do this, because opengl would always get the last index as 0. Any idea how this could happen ? Should I provide code of the actual rendering ? I checked how the index size is passed and there are no decrements, the value passed is simply the length of the indices.

The Mesh creates a buffer:

public void SetIndices(uint[] indices)
        {
            IndexCount = -1;
            GL.DeleteBuffer(VEO);
            VEO = -1;
            if (indices != null)
            {
                VEO = GL.GenBuffer();
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, VEO);
                GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(uint)), indices, BufferUsageHint.StaticDraw);
                IndexCount = indices.Length;
            }
            var mr = GameObject.Component<MeshRenderer>();
            if (mr != null)
                mr.UpdateVertexCount();
        }

and it's rendered (m.VEO is the element buffer, ElementCount is the number of triangles to draw):

GL.BindBuffer(BufferTarget.ArrayBuffer, m.VBO);
                    GL.BindVertexArray(VAO);
                    if(m.VEO > 0)
                        GL.BindBuffer(BufferTarget.ElementArrayBuffer, m.VEO);
                    if (Shader != null)
                    {
                        Shader.Use();
                        //default shader vars
                        Shader.SetUniform<float>("_time", new float[] { time });
                        Shader.SetUniform<Matrix4>("_modelViewProjection", m.GameObject.Transform.GetMatrix() * GameObject.App.ModelViewProjectionMatrix);

                        Shader.SetVertexAttributes(drawHints);

                    }
                    if (m.VEO > 0)
                        GL.DrawElements(PrimitiveType, ElementCount, DrawElementsType.UnsignedInt, m.VEO);
                    else
                        GL.DrawArrays(PrimitiveType, 0,ElementCount);
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
                    GL.BindVertexArray(0);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                    GL.UseProgram(0);
pixartist
  • 1,137
  • 2
  • 18
  • 40

1 Answers1

2

You're passing the wrong value for the last argument to DrawElements():

GL.DrawElements(PrimitiveType, ElementCount, DrawElementsType.UnsignedInt, m.VEO);

If an index buffer is bound by calling glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...), which you did, the last argument of glDrawElements() is a relative offset into this index buffer. If you want to use the index buffer from the start, which is the case in your example, the value should be 0:

GL.DrawElements(PrimitiveType, ElementCount, DrawElementsType.UnsignedInt, 0);
Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • Ah okay, the syntax help said "indices". Thanks – pixartist Jul 06 '14 at 18:07
  • The way this entry point is overloaded is very unfortunate IMHO. The last argument is an index array (pointer to indices) if no index buffer is currently bound, which explains why the argument is named `indices` in the documentation. If an index buffer is bound, it becomes an offset (in bytes) into the index buffer. – Reto Koradi Jul 06 '14 at 18:54