public static void BindVertexAttributes(int vbo, int vao, int stride, VertexAttributeMappingCollection attributes) { GL.BindVertexArray(vao); GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); var offset = 0; for (int i = 0; i < attributes.Count; i++) { var attribute = attributes[i]; GL.EnableVertexAttribArray(i); GL.VertexAttribPointer( i, attribute.Size, attribute.Type, attribute.Normalized, stride, offset); offset += attribute.Size * VertexHelper.GetVertexAttributeSize(attribute.Type); } GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindVertexArray(0); }
internal MeshAggregate(IEnumerable <MeshAttributeMapping> source) { meshAttributes = source.ToArray(); GL.GenVertexArrays(1, out vao); var indexOffset = 0; var vertexAttributes = new List <InstanceAttributeMapping>(); foreach (var mapping in meshAttributes) { var vertexStride = 0; GL.BindVertexArray(mapping.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 InstanceAttributeMapping(); 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; attribute.Divisor = mapping.Divisor; vertexAttributes.Add(attribute); } var offset = 0; GL.BindVertexArray(vao); GL.BindBuffer(BufferTarget.ArrayBuffer, mapping.Mesh.VertexBuffer); for (int i = 0; i < vertexAttributes.Count; i++) { var index = i + indexOffset; var attribute = vertexAttributes[i]; GL.EnableVertexAttribArray(index); GL.VertexAttribPointer( index, attribute.Size, attribute.Type, attribute.Normalized, vertexStride, offset); if (attribute.Divisor > 0) { GL.VertexAttribDivisor(index, attribute.Divisor); } offset += attribute.Size * VertexHelper.GetVertexAttributeSize(attribute.Type); } indexOffset += vertexAttributes.Count; vertexAttributes.Clear(); } GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindVertexArray(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); }