using System.Runtime.InteropServices; using UnitTestSharp; using Blacklight.GPUBridge; namespace Blacklight.WebGL2.UnitTests { public class WebGL2VertexLayoutTests : TestFixture { public class AttributesTests : TestFixture { // Pin every attribute to the VertexDefinition field it describes (mirrors SharpDX9VertexLayoutTests). public void OffsetsMatchTheStructFieldsTheyDescribe() { int OffsetOf(string field) => Marshal.OffsetOf(typeof(VertexDefinition), field).ToInt32(); var attributes = WebGL2VertexLayout.Attributes; CheckEqual(OffsetOf(nameof(VertexDefinition.TranslationAndVertexPosition)), attributes[0].ByteOffset); CheckEqual(OffsetOf(nameof(VertexDefinition.ScaleAndOrientation)), attributes[1].ByteOffset); CheckEqual(OffsetOf(nameof(VertexDefinition.BorderStyle)), attributes[2].ByteOffset); CheckEqual(OffsetOf(nameof(VertexDefinition.UserData_1)), attributes[3].ByteOffset); CheckEqual(OffsetOf(nameof(VertexDefinition.ClipWindowLS)), attributes[4].ByteOffset); CheckEqual(OffsetOf(nameof(VertexDefinition.SpriteDestinationRect)), attributes[5].ByteOffset); CheckEqual(OffsetOf(nameof(VertexDefinition.InsideColor)), attributes[6].ByteOffset); CheckEqual(OffsetOf(nameof(VertexDefinition.BorderColor)), attributes[7].ByteOffset); CheckEqual(OffsetOf(nameof(VertexDefinition.BorderTextureSlot)), attributes[8].ByteOffset); } public void HasOneEntryPerVertexDefinitionField() { CheckEqual(9, WebGL2VertexLayout.Attributes.Length); } public void LocationsAreSequentialStartingAtZero() { var attributes = WebGL2VertexLayout.Attributes; for (int i = 0; i < attributes.Length; ++i) { CheckEqual(i, attributes[i].Location); } } public void EveryAttributeHasFourComponents() { foreach (var attribute in WebGL2VertexLayout.Attributes) { CheckEqual(4, attribute.ComponentCount); } } public void PackedColorsAreNormalizedUnsignedBytes() { var insideColor = WebGL2VertexLayout.Attributes[6]; var borderColor = WebGL2VertexLayout.Attributes[7]; CheckEqual(WebGL2AttributeType.UnsignedByte, insideColor.Type); CheckTrue(insideColor.Normalized); CheckEqual(WebGL2AttributeType.UnsignedByte, borderColor.Type); CheckTrue(borderColor.Normalized); } public void TextureSlotsAreUnnormalizedUnsignedBytes() { var textureSlots = WebGL2VertexLayout.Attributes[8]; CheckEqual(WebGL2AttributeType.UnsignedByte, textureSlots.Type); CheckFalse(textureSlots.Normalized); } public void RemainingAttributesAreUnnormalizedFloats() { var attributes = WebGL2VertexLayout.Attributes; for (int i = 0; i < 6; ++i) { CheckEqual(WebGL2AttributeType.Float, attributes[i].Type); CheckFalse(attributes[i].Normalized); } } } public class ForInteropArraysTests : TestFixture { public void HaveOneEntryPerAttribute() { int expected = WebGL2VertexLayout.Attributes.Length; CheckEqual(expected, WebGL2VertexLayout.LocationsForInterop.Length); CheckEqual(expected, WebGL2VertexLayout.ComponentCountsForInterop.Length); CheckEqual(expected, WebGL2VertexLayout.TypesForInterop.Length); CheckEqual(expected, WebGL2VertexLayout.NormalizedFlagsForInterop.Length); CheckEqual(expected, WebGL2VertexLayout.ByteOffsetsForInterop.Length); } public void EachIndexMatchesTheCorrespondingAttribute() { var attributes = WebGL2VertexLayout.Attributes; for (int i = 0; i < attributes.Length; ++i) { var attribute = attributes[i]; CheckEqual((double)attribute.Location, WebGL2VertexLayout.LocationsForInterop[i]); CheckEqual((double)attribute.ComponentCount, WebGL2VertexLayout.ComponentCountsForInterop[i]); CheckEqual((double)(int)attribute.Type, WebGL2VertexLayout.TypesForInterop[i]); CheckEqual(attribute.Normalized ? 1.0 : 0.0, WebGL2VertexLayout.NormalizedFlagsForInterop[i]); CheckEqual((double)attribute.ByteOffset, WebGL2VertexLayout.ByteOffsetsForInterop[i]); } } } } }