public void TestTransform() { // Define variables and constants ModelInstanceManager mim = new ModelInstanceManager(); ConstantBuffer <Vector4> fsCB = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite); FragmentShader fs = new FragmentShader(@"Tests\SimpleFS.cso", new ConstantBufferBinding(0U, "MaterialProperties", fsCB)); Material testMat = new Material("TestMat", fs); SceneLayer testLayer = Scene.CreateLayer("TestLayer"); ModelInstanceHandle testHandle = mim.AllocateInstance(testMat.Index, 0U, testLayer.Index, Transform.DEFAULT_TRANSFORM); // Set up context // Execute testHandle.Transform = new Transform(Vector3.ONE * 4f, Quaternion.IDENTITY, Vector3.ONE * -15f); // Assert outcome Assert.AreEqual(new Transform(Vector3.ONE * 4f, Quaternion.IDENTITY, Vector3.ONE * -15f), testHandle.Transform); testHandle.Dispose(); testLayer.Dispose(); mim.Dispose(); testMat.Dispose(); fs.Dispose(); fsCB.Dispose(); }
public HUDTexture(FragmentShader fragmentShader, SceneLayer targetLayer, SceneViewport targetViewport) { lock (staticMutationLock) { if (hudTextureModel == null) { throw new InvalidOperationException("HUD Texture Model must be set before creating any HUDTexture objects."); } } this.targetViewport = targetViewport; this.material = new Material("HUDTexture Mat", fragmentShader); this.curModelInstance = targetLayer.CreateModelInstance(hudTextureModel.Value, material, Transform.DEFAULT_TRANSFORM); this.fsTexColorMultiplyBinding = (ConstantBufferBinding)fragmentShader.GetBindingByIdentifier(HUDFS_TEX_PROPS_CBB_NAME); this.fsTexBinding = (ResourceViewBinding)fragmentShader.GetBindingByIdentifier(HUDFS_TEX_BINDING_NAME); material.SetMaterialConstantValue(fsTexColorMultiplyBinding, color); targetViewport.TargetWindow.WindowResized += WindowResize; this.fragmentShader = fragmentShader; this.sceneLayer = targetLayer; }
public void _ADD_VEGG_ROT(ModelInstanceHandle mih, Quaternion rot) { lock (InstanceMutationLock) { __VEGG_MIH_ARR[mih] *= rot; } }
public unsafe void TestCreateAndDestroyInstance() { // Define variables and constants const int NUM_INSTANCES = 1000; var gcb = new GeometryCacheBuilder <TestVertex>(); gcb.AddModel("TCADI_a", new[] { new TestVertex(Vector3.ONE), new TestVertex(Vector3.LEFT), }, new[] { 0U, 1U, 1U, 0U, 1U, 0U }); gcb.AddModel("TCADI_b", new[] { new TestVertex(Vector3.RIGHT), new TestVertex(Vector3.UP), }, new[] { 0U, 1U, 1U, 0U, 1U, 0U }); gcb.AddModel("TCADI_c", new[] { new TestVertex(Vector3.ZERO), new TestVertex(Vector3.DOWN), }, new[] { 0U, 1U, 1U, 0U, 1U, 0U }); GeometryCache testCache = gcb.Build(); SceneLayer testLayerA = Scene.CreateLayer("Test Layer A"); SceneLayer testLayerB = Scene.CreateLayer("Test Layer B"); ConstantBuffer <Vector4> fsColorBuffer = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite); FragmentShader fs = new FragmentShader(@"Tests\SimpleFS.cso", new ConstantBufferBinding(0U, "MaterialProperties", fsColorBuffer)); Material testMatA = new Material("Brick", fs); Material testMatB = new Material("Wood", fs); // Set up context // Execute ModelInstanceHandle[] instanceArr = new ModelInstanceHandle[NUM_INSTANCES]; for (int i = 0; i < NUM_INSTANCES; ++i) { Transform transform = new Transform( Vector3.ONE * i, Quaternion.FromAxialRotation(Vector3.UP, i), Vector3.ONE * -i ); if (i % 5 == 0) { instanceArr[i] = testLayerA.CreateModelInstance(new ModelHandle(testCache.ID, (uint)(i % 3)), (i % 2 == 0 ? testMatA : testMatB), transform); } else { instanceArr[i] = testLayerB.CreateModelInstance(new ModelHandle(testCache.ID, (uint)(i % 3)), (i % 2 == 0 ? testMatA : testMatB), transform); } } // Assert outcome RenderingModule.RenderStateBarrier.FreezeMutations(); // Cheeky, but we have to on debug mode (and it's re-entrant for now, so no problem) var instanceData = testCache.GetModelInstanceData(); for (int i = 0; i < NUM_INSTANCES; ++i) { Material instanceMaterial = Material.GetMaterialByIndex(instanceArr[i].MaterialIndex); ModelInstanceManager.MIDArray materialDataArray = instanceData.First(kvp => kvp.Key == instanceMaterial).Value; Assert.AreEqual((i % 2 == 0 ? testMatA : testMatB), instanceMaterial); Assert.AreEqual((i % 5 == 0 ? testLayerA : testLayerB), Scene.GetLayerByIndex(materialDataArray.Data[GetMIHInstanceIndex(instanceArr[i])].SceneLayerIndex)); Assert.IsTrue(materialDataArray.Data[GetMIHInstanceIndex(instanceArr[i])].InUse); Assert.AreEqual((uint)(i % 3), materialDataArray.Data[GetMIHInstanceIndex(instanceArr[i])].ModelIndex); Assert.AreEqual( new Transform( Vector3.ONE * i, Quaternion.FromAxialRotation(Vector3.UP, i), Vector3.ONE * -i ), instanceArr[i].Transform ); Assert.AreEqual(instanceArr[i].Transform, materialDataArray.Data[GetMIHInstanceIndex(instanceArr[i])].Transform); instanceArr[i].Dispose(); Assert.IsFalse(materialDataArray.Data[GetMIHInstanceIndex(instanceArr[i])].InUse); } RenderingModule.RenderStateBarrier.UnfreezeMutations(); testCache.Dispose(); testMatA.Dispose(); testMatB.Dispose(); testLayerA.Dispose(); testLayerB.Dispose(); fs.Dispose(); fsColorBuffer.Dispose(); }
private uint GetMIHInstanceIndex(ModelInstanceHandle mih) { FieldInfo fi = typeof(ModelInstanceHandle).GetField("instanceIndex", BindingFlags.NonPublic | BindingFlags.Instance); return((uint)fi.GetValue(mih)); }
public void TestAllMethods() { // Define variables and constants ModelInstanceManager testMIM = new ModelInstanceManager(); const int NUM_ALLOCATIONS = 3000; const int NUM_MODELS = 7; const int NUM_MATERIALS = 11; const int NUM_SCENE_LAYERS = 3; ConstantBuffer <Vector4> fsCBuffer = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite); FragmentShader testFS = new FragmentShader(@"Tests\SimpleFS.cso", new ConstantBufferBinding(0U, "MaterialProperties", fsCBuffer)); Material[] materials = new Material[NUM_MATERIALS]; for (int i = 0; i < NUM_MATERIALS; ++i) { materials[i] = new Material(i.ToString(), testFS); } // Set up context ModelInstanceHandle[] instances = new ModelInstanceHandle[NUM_ALLOCATIONS]; // Execute for (int i = 0; i < NUM_ALLOCATIONS; i++) { Transform initialTransform = new Transform( Vector3.ONE * i, Quaternion.FromAxialRotation(Vector3.ONE * (i + 1), MathUtils.PI), Vector3.ONE * -i ); instances[i] = testMIM.AllocateInstance(materials[i % NUM_MATERIALS].Index, (uint)i % NUM_MODELS, (uint)i % NUM_SCENE_LAYERS, initialTransform); } for (int i = 0; i < NUM_ALLOCATIONS; i += 2) { instances[i].Transform = instances[i].Transform.With(scale: Vector3.FORWARD * i); } // Assert outcome RenderingModule.RenderStateBarrier.FreezeMutations(); ArraySlice <KeyValuePair <Material, ModelInstanceManager.MIDArray> > midData = testMIM.GetModelInstanceData(); RenderingModule.RenderStateBarrier.UnfreezeMutations(); Assert.AreEqual(NUM_ALLOCATIONS, midData.Sum(kvp => { unsafe { int val = 0; for (int i = 0; i < kvp.Value.Length; ++i) { if (kvp.Value.Data[i].InUse) { ++val; } } return(val); } })); unsafe { foreach (KeyValuePair <Material, ModelInstanceManager.MIDArray> kvp in midData) { Assert.IsTrue(materials.Contains(kvp.Key)); for (uint i = 0U; i < kvp.Value.Length; ++i) { if (!kvp.Value.Data[i].InUse) { continue; } Assert.AreEqual(1, instances.Count(mih => mih.Transform == kvp.Value.Data[i].Transform)); } } } materials.ForEach(mat => mat.Dispose()); testFS.Dispose(); fsCBuffer.Dispose(); }