internal void Apply(Shader shader, IntPtr offset)
{
VertexDeclarationAttributeInfo attrInfo;
int shaderHash = shader.GetHashCode();
if (!shaderAttributeInfo.TryGetValue(shaderHash, out attrInfo))
{
// Get the vertex attribute info and cache it
attrInfo = new VertexDeclarationAttributeInfo(GraphicsDevice.MaxVertexAttributes);
foreach (var ve in _elements)
{
var attributeLocation = shader.GetAttribLocation(ve.VertexElementUsage, ve.UsageIndex);
// XNA appears to ignore usages it can't find a match for, so we will do the same
if (attributeLocation >= 0)
{
attrInfo.Elements.Add(new VertexDeclarationAttributeInfo.Element()
{
Offset = ve.Offset,
AttributeLocation = attributeLocation,
NumberOfElements = ve.VertexElementFormat.OpenGLNumberOfElements(),
VertexAttribPointerType = ve.VertexElementFormat.OpenGLVertexAttribPointerType(),
Normalized = ve.OpenGLVertexAttribNormalized(),
});
attrInfo.EnabledAttributes[attributeLocation] = true;
}
}
shaderAttributeInfo.Add(shaderHash, attrInfo);
}
// Apply the vertex attribute info
foreach (var element in attrInfo.Elements)
{
GL.VertexAttribPointer(element.AttributeLocation,
element.NumberOfElements,
element.VertexAttribPointerType,
element.Normalized,
this.VertexStride,
(IntPtr)(offset.ToInt64() + element.Offset));
GraphicsExtensions.CheckGLError();
}
GraphicsDevice.SetVertexAttributeArray(attrInfo.EnabledAttributes);
}