private void SetVertexAttributes(OpenGLVertexInputLayout inputlayout, VertexBuffer[] vertexBuffers)
        {
            int totalSlotsBound = 0;

            for (int i = 0; i < inputlayout.VBLayoutsBySlot.Length; i++)
            {
                OpenGLVertexInput  input = inputlayout.VBLayoutsBySlot[i];
                OpenGLVertexBuffer vb    = ((OpenGLVertexBuffer)vertexBuffers[i]);
                vb.Apply();
                for (int slot = 0; slot < input.Elements.Length; slot++)
                {
                    ref OpenGLVertexInputElement element = ref input.Elements[slot]; // Large structure -- use by reference.
                    int actualSlot = totalSlotsBound + slot;
                    if (actualSlot >= _vertexAttributesBound)
                    {
                        GL.EnableVertexAttribArray(actualSlot);
                    }
                    GL.VertexAttribPointer(actualSlot, element.ElementCount, element.Type, element.Normalized, vb.Stride, element.Offset);

                    int stepRate = element.InstanceStepRate;
                    if (_vertexAttribDivisors[actualSlot] != stepRate)
                    {
                        GL.VertexAttribDivisor(actualSlot, stepRate);
                        _vertexAttribDivisors[actualSlot] = stepRate;
                    }
                }

                totalSlotsBound += input.Elements.Length;
            }
        public OpenGLVertexInput(VertexInputDescription genericInput)
        {
            VertexSizeInBytes = genericInput.VertexSizeInBytes;
            Elements          = new OpenGLVertexInputElement[genericInput.Elements.Length];
            int offset = 0;

            for (int i = 0; i < Elements.Length; i++)
            {
                var genericElement = genericInput.Elements[i];
                Elements[i] = new OpenGLVertexInputElement(genericElement, offset);
                offset     += genericElement.SizeInBytes;
            }
        }