OpenTK省略了elementbuffer中的最后一个索引?

时间:2014-07-06 13:05:50

标签: opengl indexing buffer opentk

我有一个像这样定义的Cube网格:

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;
        }

现在你可以看到我在索引末尾加了一个“1”。我必须这样做,因为opengl总是将最后一个索引设为0.任何想法如何发生这种情况?我应该提供实际渲染的代码吗?我检查了索引大小是如何传递的,并且没有减少,传递的值只是索引的长度。

Mesh创建一个缓冲区:

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();
        }

并且它被渲染(m.VEO是元素缓冲区,ElementCount是要绘制的三角形数):

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);

1 个答案:

答案 0 :(得分:2)

您将最后一个参数的错误值传递给DrawElements()

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

如果通过调用glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)来绑定索引缓冲区,则glDrawElements()的最后一个参数是此索引缓冲区的相对偏移量。如果要从头开始使用索引缓冲区(在示例中就是这种情况),则值应为0

GL.DrawElements(PrimitiveType, ElementCount, DrawElementsType.UnsignedInt, 0);