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 int SetVertexAttributes(int vertexBufferSlot, OpenGLVertexBuffer vb, int previousAttributesBound)
        {
            // TODO: Related to OpenGLRenderContext.PlatformSetVertexBuffer()
            // These attributes should be lazily set on a draw call or something.
            if (vertexBufferSlot <= VBLayoutsBySlot.Length)
            {
                return(previousAttributesBound);
            }

            int baseSlot = GetSlotBaseIndex(vertexBufferSlot);
            OpenGLMaterialVertexInput input = VBLayoutsBySlot[vertexBufferSlot];

            vb.Apply();
            for (int i = 0; i < input.Elements.Length; i++)
            {
                OpenGLMaterialVertexInputElement element = input.Elements[i];
                int slot = baseSlot + i;
                GL.EnableVertexAttribArray(slot);
                GL.VertexAttribPointer(slot, element.ElementCount, element.Type, element.Normalized, input.VertexSizeInBytes, element.Offset);
            }
            for (int extraSlot = input.Elements.Length; extraSlot < previousAttributesBound; extraSlot++)
            {
                GL.DisableVertexAttribArray(extraSlot);
            }

            return(input.Elements.Length);
        }
        public void SetAndGet_Array()
        {
            OpenGLVertexBuffer vb = (OpenGLVertexBuffer)_factory.CreateVertexBuffer(1, false);

            float[] vertexData = Enumerable.Range(0, 150).Select(i => (float)i).ToArray();
            vb.SetVertexData(vertexData, new VertexDescriptor(4, 1, 0, IntPtr.Zero));

            float[] returned = new float[vertexData.Length];
            vb.GetData(returned);
            Assert.Equal(vertexData, returned);
        }
        public void SetAndGet_Array_Offset()
        {
            OpenGLVertexBuffer vb = (OpenGLVertexBuffer)_factory.CreateVertexBuffer(1, false);

            float[] vertexData = Enumerable.Range(0, 150).Select(i => (float)i).ToArray();
            vb.SetVertexData(vertexData, new VertexDescriptor(sizeof(float), 1, 0, IntPtr.Zero), 250);

            float[] returned = new float[vertexData.Length + 250];
            vb.GetData(returned);
            for (int i = 250; i < returned.Length; i++)
            {
                Assert.Equal(vertexData[i - 250], returned[i]);
            }
        }