private static List <InterleavedSectionBase> ScanTypeSections() { List <InterleavedSectionBase> typeSections; if (_TypeSections.TryGetValue(typeof(T), out typeSections)) { return(typeSections); } // Cache for type uint itemSize = (uint)Marshal.SizeOf(typeof(T)); typeSections = new List <InterleavedSectionBase>(); foreach (FieldInfo field in typeof(T).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { typeSections.Add(new InterleavedSectionBase { ItemType = ArrayBufferItem.GetArrayType(field.FieldType), Normalized = false, Offset = Marshal.OffsetOf(typeof(T), field.Name), Stride = new IntPtr(itemSize) }); } _TypeSections.Add(typeof(T), typeSections); return(typeSections); }
private static List <InterleavedSectionBase> ScanTypeSections() { List <InterleavedSectionBase> typeSections; // Determine array item size uint itemSize = (uint)Marshal.SizeOf(typeof(T)); if (_TypeSections.TryGetValue(typeof(T), out typeSections) == false) { // Cache for type typeSections = new List <InterleavedSectionBase>(); foreach (FieldInfo field in typeof(T).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { InterleavedSectionBase structSection = new InterleavedSectionBase(); structSection.ItemType = ArrayBufferItem.GetArrayType(field.FieldType); structSection.Normalized = false; structSection.Offset = Marshal.OffsetOf(typeof(T), field.Name); structSection.Stride = new IntPtr(itemSize); typeSections.Add(structSection); } _TypeSections.Add(typeof(T), typeSections); } return(typeSections); }
/// <summary> /// Enable the generic vertex attribute. /// </summary> /// <param name="ctx"> /// The <see cref="GraphicsContext"/> on which the shader program is bound. /// </param> /// <param name="attributeBinding"> /// The <see cref="ShaderProgram.AttributeBinding"/> representing the generic vertex attribute. /// </param> internal virtual void EnableVertexAttribute(GraphicsContext ctx, uint location, ShaderAttributeType type) { ArrayBufferObjectBase.IArraySection arraySection = ArrayBuffer.GetArraySection(ArraySectionIndex); int arrayBaseType = (int)arraySection.ItemType.GetVertexBaseType(); int arrayLength = (int)arraySection.ItemType.GetArrayLength(); int arrayStride = arraySection.Stride.ToInt32(); // Avoid rendundant buffer binding and relative vertex array setup if (ctx.Extensions.VertexArrayObject_ARB && IsDirty == false) { // CheckVertexAttribute(ctx, location); return; } // Bind the array buffer ctx.Bind(ArrayBuffer); // Bind varying attribute to currently bound buffer object switch (ArrayBufferItem.GetArrayBaseType(type)) { case VertexBaseType.Float: Gl.VertexAttribPointer( location, arrayLength, arrayBaseType, arraySection.Normalized, arrayStride, arraySection.Offset ); break; case VertexBaseType.Int: case VertexBaseType.UInt: Gl.VertexAttribIPointer( location, arrayLength, arrayBaseType, arrayStride, arraySection.Offset ); break; case VertexBaseType.Double: Gl.VertexAttribLPointer( location, arrayLength, arrayBaseType, arrayStride, arraySection.Offset ); break; default: throw new NotSupportedException(String.Format("vertex attribute type {0} not supported", type)); } // Enable vertex attribute Gl.EnableVertexAttribArray(location); }
/// <summary> /// Construct an ArrayBufferObjectInterleaved specifying its item layout on GPU side. /// </summary> /// <param name="format"> /// A <see cref="ArrayBufferItemType"/> describing the item base type on GPU side. /// </param> /// <param name="hint"> /// An <see cref="BufferObjectHint"/> that specify the data buffer usage hints. /// </param> public ArrayBufferObjectInterleaved(BufferObjectHint hint) : base(hint) { try { // Determine array item size ItemSize = (uint)Marshal.SizeOf(typeof(T)); // Detect interleaved fields using reflection (cached) List <InterleavedSectionBase> typeSections; if (_TypeSections.TryGetValue(typeof(T), out typeSections) == false) { // Cache for type typeSections = new List <InterleavedSectionBase>(); foreach (FieldInfo field in typeof(T).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { InterleavedSectionBase structSection = new InterleavedSectionBase(); structSection.ItemType = ArrayBufferItem.GetArrayType(field.FieldType); structSection.Normalized = false; structSection.Offset = Marshal.OffsetOf <T>(field.Name); structSection.Stride = new IntPtr(ItemSize); typeSections.Add(structSection); } _TypeSections.Add(typeof(T), typeSections); } // Get array sections for this instance _InterleavedSections = typeSections.ConvertAll(delegate(InterleavedSectionBase item) { return(new InterleavedSection(this, item)); }); } catch { // Avoid finalizer assertion failure (don't call dispose since it's virtual) GC.SuppressFinalize(this); throw; } }