/// <summary> /// Tries to find an <see cref="ActiveVertexAttrib"/> in this <see cref="ShaderProgram"/> with /// the specified location. /// </summary> /// <param name="location">The location to look for an <see cref="ActiveVertexAttrib"/> at.</param> /// <param name="attrib">The <see cref="ActiveVertexAttrib"/> that was found, if one was found.</param> /// <returns>Whether an attribute was found in said location.</returns> public bool TryFindAttributeByLocation(int location, out ActiveVertexAttrib attrib) { for (int i = 0; i < activeAttribs.Length; i++) { if (activeAttribs[i].Location == location) { attrib = activeAttribs[i]; return(true); } } attrib = default; return(false); }
/// <summary> /// Queries vertex attribute data from a compiled shader program and returns an /// array with all the resulting <see cref="ActiveVertexAttrib"/>-s. /// </summary> /// <param name="graphicsDevice">The <see cref="GraphicsDevice"/> to use for gl calls.</param> /// <param name="programHandle">The gl handle of the shader program to query attribs for.</param> private static ActiveVertexAttrib[] CreateActiveAttribArray(GraphicsDevice graphicsDevice, uint programHandle) { // We query the total amount of attributes we'll be reading from OpenGL graphicsDevice.GL.GetProgram(programHandle, ProgramPropertyARB.ActiveAttributes, out int attribCount); // We'll be storing the attributes in this list and then turning it into an array, because we can't // know for sure how many attributes we'll have at the end, we just know it's be <= than attribCount ActiveVertexAttrib[] attribList = new ActiveVertexAttrib[attribCount]; int attribListIndex = 0; // We query all the ShaderProgram's attributes one by one and add them to attribList for (uint i = 0; i < attribCount; i++) { ActiveVertexAttrib a = new ActiveVertexAttrib(graphicsDevice, programHandle, i); if (a.Location >= 0) // Sometimes other stuff shows up, such as gl_InstanceID with location -1. { attribList[attribListIndex++] = a; // We should, of course, filter these out. } } // If, for any reason, we didn't write the whole attribList array, we trim it down before saving it in attributes ActiveVertexAttrib[] attributes; if (attribListIndex == attribList.Length) { attributes = attribList; } else { attributes = new ActiveVertexAttrib[attribListIndex]; Array.Copy(attribList, attributes, attribListIndex); attributes = attribList; } // The attributes don't always appear ordered by location, so let's sort them now Array.Sort(attributes, (x, y) => x.Location.CompareTo(y.Location)); return(attributes); }