Пример #1
0
        static void BindInstanceAttributes(MeshInstanced instance, int stride, InstanceAttributeMappingCollection attributes)
        {
            var vertexStride = 0;
            var mesh = instance.InstanceMesh;
            var vertexAttributes = new List<VertexAttributeMapping>();
            GL.BindVertexArray(mesh.VertexArray);
            for (int i = 0; ; i++)
            {
                int enabled;
                GL.GetVertexAttrib(i, VertexAttribParameter.ArrayEnabled, out enabled);
                if (enabled == 0) break;

                int size, type, normalized, vstride;
                var attribute = new VertexAttributeMapping();
                GL.GetVertexAttrib(i, VertexAttribParameter.ArraySize, out size);
                GL.GetVertexAttrib(i, VertexAttribParameter.ArrayType, out type);
                GL.GetVertexAttrib(i, VertexAttribParameter.ArrayNormalized, out normalized);
                GL.GetVertexAttrib(i, VertexAttribParameter.ArrayStride, out vstride);
                if (vertexStride == 0) vertexStride = vstride;
                else if (vstride != vertexStride)
                {
                    throw new InvalidOperationException("Meshes with interleaved vertex buffers are not supported.");
                }

                attribute.Size = size;
                attribute.Type = (VertexAttribPointerType)type;
                attribute.Normalized = normalized != 0 ? true : false;
                vertexAttributes.Add(attribute);
            }

            var offset = 0;
            GL.BindVertexArray(instance.VertexArray);
            GL.BindBuffer(BufferTarget.ArrayBuffer, mesh.VertexBuffer);
            for (int i = 0; i < vertexAttributes.Count; i++)
            {
                var attribute = vertexAttributes[i];
                GL.EnableVertexAttribArray(i);
                GL.VertexAttribPointer(
                    i, attribute.Size,
                    attribute.Type,
                    attribute.Normalized,
                    vertexStride, offset);
                offset += attribute.Size * VertexHelper.GetVertexAttributeSize(attribute.Type);
            }

            offset = 0;
            GL.BindBuffer(BufferTarget.ArrayBuffer, instance.VertexBuffer);
            for (int i = 0; i < attributes.Count; i++)
            {
                var attribute = attributes[i];
                var index = i + vertexAttributes.Count;
                GL.EnableVertexAttribArray(index);
                GL.VertexAttribPointer(
                    index, attribute.Size,
                    attribute.Type,
                    attribute.Normalized,
                    stride, offset);
                GL.VertexAttribDivisor(index, attribute.Divisor);
                offset += attribute.Size * VertexHelper.GetVertexAttributeSize(attribute.Type);
            }

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.BindVertexArray(0);
        }