public void ShouldRejectDuplicateModelNames()
        {
            GeometryCacheBuilder <DefaultVertex> gcbA = new GeometryCacheBuilder <DefaultVertex>();

            gcbA.AddModel("SRDMN_A", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            gcbA.AddModel("SRDMN_B", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });

            GeometryCache gcA = gcbA.Build();

            GeometryCacheBuilder <DefaultVertex> gcbB = new GeometryCacheBuilder <DefaultVertex>();

            gcbB.AddModel("SRDMN_1", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            gcbB.AddModel("SRDMN_2", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            gcbB.AddModel("SRDMN_3", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            GeometryCache gcB = gcbB.Build();

            GeometryCacheBuilder <DefaultVertex> gcbC = new GeometryCacheBuilder <DefaultVertex>();

            gcbC.AddModel("SRDMN_1", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            try {
                gcbC.Build();
                Assert.Fail();
            }
            catch (InvalidOperationException) { }

            gcbC = new GeometryCacheBuilder <DefaultVertex>();
            gcbC.AddModel("SRDMN_A", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            try {
                gcbC.Build();
                Assert.Fail();
            }
            catch (InvalidOperationException) { }

            gcbC = new GeometryCacheBuilder <DefaultVertex>();
            gcbC.AddModel("SRDMN_X", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            gcbC.AddModel("SRDMN_Y", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            gcbC.AddModel("SRDMN_Z", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            gcbC.AddModel("SRDMN_Z", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            try {
                gcbC.Build();
                Assert.Fail();
            }
            catch (InvalidOperationException) { }

            gcA.Dispose();
            gcB.Dispose();
        }
Ejemplo n.º 2
0
        public void TestSetInputLayout()
        {
            GeometryCacheBuilder <DefaultVertex> gcb = new GeometryCacheBuilder <DefaultVertex>();

            gcb.AddModel("TSIL_a", new DefaultVertex[] { new DefaultVertex(Vector3.ONE) }, new uint[] { 0U });
            GeometryCache           cache  = gcb.Build();
            ConstantBuffer <Matrix> vpMat  = BufferFactory.NewConstantBuffer <Matrix>().WithUsage(ResourceUsage.DiscardWrite);
            VertexShader            shader = new VertexShader(
                @"Tests\SimpleVS.cso",
                new VertexInputBinding(0U, "INSTANCE_TRANSFORM"),
                new ConstantBufferBinding(0U, "CameraTransform", vpMat),
                new VertexInputBinding(1U, "POSITION")
                );

            GeometryInputLayout gil = cache.GetInputLayout(shader);

            RenderCommand testCommand = RenderCommand.SetInputLayout(gil);

            Assert.AreEqual(RenderCommandInstruction.SetInputLayout, testCommand.Instruction);
            Assert.AreEqual((RenderCommandArgument)(IntPtr)gil.ResourceHandle, testCommand.Arg1);

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.SetInputLayout(null);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif

            shader.Dispose();
            vpMat.Dispose();
            cache.Dispose();
            gil.Dispose();

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.SetInputLayout(gil);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif
        }
Ejemplo n.º 3
0
        public void TestGettingModelsByName()
        {
            GeometryCacheBuilder <DefaultVertex> gcbA = new GeometryCacheBuilder <DefaultVertex>();
            ModelHandle modelA = gcbA.AddModel("TGMBN_A", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            ModelHandle modelB = gcbA.AddModel("TGMBN_B", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });

            GeometryCache gcA = gcbA.Build();

            GeometryCacheBuilder <DefaultVertex> gcbB = new GeometryCacheBuilder <DefaultVertex>();
            ModelHandle   model1 = gcbB.AddModel("TGMBN_1", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            ModelHandle   model2 = gcbB.AddModel("TGMBN_2", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            ModelHandle   model3 = gcbB.AddModel("TGMBN_3", new[] { new DefaultVertex(Vector3.ONE) }, new[] { 1U });
            GeometryCache gcB    = gcbB.Build();

            Assert.AreEqual(modelA, gcA.GetModelByName("TGMBN_A"));
            Assert.AreEqual(model3, gcB.GetModelByName("TGMBN_3"));

            Assert.AreEqual(model1, GeometryCache.GloballyGetModelByName("TGMBN_1"));
            Assert.AreEqual(model2, GeometryCache.GloballyGetModelByName("TGMBN_2"));
            Assert.AreEqual(modelB, GeometryCache.GloballyGetModelByName("TGMBN_B"));

            try {
                gcA.GetModelByName("TGMBN_1");
                Assert.Fail();
            }
            catch (KeyNotFoundException) { }

            try {
                gcB.GetModelByName("TGMBN_B");
                Assert.Fail();
            }
            catch (KeyNotFoundException) { }

            try {
                GeometryCache.GloballyGetModelByName("TGMBN_C");
                Assert.Fail();
            }
            catch (KeyNotFoundException) { }
        }
Ejemplo n.º 4
0
        public static Font Load(string fontFile, FragmentShader textFS, uint?lineHeightPixels, int?kerningPixels)
        {
            Assure.NotNull(fontFile);
            Assure.NotNull(textFS);
            Assure.False(textFS.IsDisposed);
            if (!IOUtils.IsValidFilePath(fontFile) || !File.Exists(fontFile))
            {
                throw new FileNotFoundException("File '" + fontFile + "' not found: Could not load font.");
            }

            XDocument fontDocument  = XDocument.Load(fontFile, LoadOptions.None);
            XElement  root          = fontDocument.Root;
            XElement  commonElement = root.Element("common");

            if (commonElement == null)
            {
                throw new InvalidOperationException("Could not find common element in given font file.");
            }

            string name = Path.GetFileNameWithoutExtension(fontFile).CapitalizeFirst();
            uint   texWidth;
            uint   texHeight;

            try {
                texWidth  = uint.Parse(commonElement.Attribute("scaleW").Value);
                texHeight = uint.Parse(commonElement.Attribute("scaleH").Value);
                if (lineHeightPixels == null)
                {
                    lineHeightPixels = uint.Parse(commonElement.Attribute("lineHeight").Value) / 2U;
                }
            }
            catch (Exception e) {
                throw new InvalidOperationException("Could not read scaleW, scaleH, or lineHeight value!", e);
            }

            XElement pagesElement = root.Element("pages");
            IEnumerable <XElement> pageElements = pagesElement.Elements("page");

            ITexture2D[]         pageArray          = new ITexture2D[pageElements.Count()];
            ShaderResourceView[] characterPageViews = new ShaderResourceView[pageArray.Length];

            foreach (XElement pageElement in pageElements)
            {
                int    id;
                string filename;
                try {
                    id       = int.Parse(pageElement.Attribute("id").Value);
                    filename = pageElement.Attribute("file").Value;
                }
                catch (Exception e) {
                    throw new InvalidOperationException("Could not read page ID or filename for page " + pageElement + ".", e);
                }

                string fullFilename = Path.Combine(Path.GetDirectoryName(fontFile), filename);
                if (!IOUtils.IsValidFilePath(fullFilename) || !File.Exists(fullFilename))
                {
                    throw new InvalidOperationException("Page file '" + fullFilename + "' does not exist!");
                }
                if (id < 0 || id >= pageArray.Length || pageArray[id] != null)
                {
                    throw new InvalidOperationException("Invalid or duplicate page ID '" + id + "'.");
                }

                pageArray[id] = TextureFactory.LoadTexture2D()
                                .WithFilePath(fullFilename)
                                .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                                .WithUsage(ResourceUsage.Immutable)
                                .Create();

                characterPageViews[id] = pageArray[id].CreateView();
            }

            GeometryCacheBuilder <DefaultVertex> characterCacheBuilder = new GeometryCacheBuilder <DefaultVertex>();
            Dictionary <char, FontCharacter>     charMap = new Dictionary <char, FontCharacter>();
            XElement charsElement = root.Element("chars");

            foreach (XElement charElement in charsElement.Elements("char"))
            {
                char unicodeValue;
                uint x, y, width, height;
                int  pageID, yOffset;

                try {
                    unicodeValue = (char)short.Parse(charElement.Attribute("id").Value);
                    x            = uint.Parse(charElement.Attribute("x").Value);
                    y            = uint.Parse(charElement.Attribute("y").Value);
                    width        = uint.Parse(charElement.Attribute("width").Value);
                    height       = uint.Parse(charElement.Attribute("height").Value);
                    pageID       = int.Parse(charElement.Attribute("page").Value);
                    yOffset      = int.Parse(charElement.Attribute("yoffset").Value);
                }
                catch (Exception e) {
                    throw new InvalidOperationException("Could not acquire character ID, page ID, or dimensions for char " + charElement + ".", e);
                }

                Rectangle charMapBoundary = new Rectangle(x, y, width, height);

                ModelHandle modelHandle = characterCacheBuilder.AddModel(
                    "Font_" + name + "_Character_" + unicodeValue,
                    new[] {
                    new DefaultVertex(
                        new Vector3(0f, 0f, 1f),
                        Vector3.BACKWARD, new Vector2(
                            charMapBoundary.GetCornerX(Rectangle.RectangleCorner.BottomLeft) / texWidth,
                            charMapBoundary.GetCornerY(Rectangle.RectangleCorner.BottomLeft) / texHeight
                            )),
                    new DefaultVertex(
                        new Vector3(charMapBoundary.Width, 0f, 1f),
                        Vector3.BACKWARD, new Vector2(
                            charMapBoundary.GetCornerX(Rectangle.RectangleCorner.BottomRight) / texWidth,
                            charMapBoundary.GetCornerY(Rectangle.RectangleCorner.BottomRight) / texHeight
                            )),
                    new DefaultVertex(
                        new Vector3(charMapBoundary.Width, -charMapBoundary.Height, 1f),
                        Vector3.BACKWARD, new Vector2(
                            charMapBoundary.GetCornerX(Rectangle.RectangleCorner.TopRight) / texWidth,
                            charMapBoundary.GetCornerY(Rectangle.RectangleCorner.TopRight) / texHeight
                            )),
                    new DefaultVertex(
                        new Vector3(0f, -charMapBoundary.Height, 1f),
                        Vector3.BACKWARD, new Vector2(
                            charMapBoundary.GetCornerX(Rectangle.RectangleCorner.TopLeft) / texWidth,
                            charMapBoundary.GetCornerY(Rectangle.RectangleCorner.TopLeft) / texHeight
                            )),
                },
                    new[] { 0U, 1U, 3U, 1U, 2U, 3U }
                    );

                //yOffset = 0;
                //if (unicodeValue == '.') yOffset = (int) (lineHeightPixels.Value * 0.9f);

                charMap.Add(
                    unicodeValue,
                    new FontCharacter(
                        unicodeValue,
                        charMapBoundary,
                        modelHandle,
                        textFS,
                        characterPageViews[pageID],
                        yOffset
                        )
                    );
            }

            if (kerningPixels == null)
            {
                kerningPixels = (int)(charMap.Values.Max(value => value.Boundary.Width) * 0.15f);
            }

            uint maxCharHeight = (uint)charMap.Values.Max(fc => fc.Boundary.Height);

            return(new Font(
                       name,
                       lineHeightPixels.Value,
                       kerningPixels.Value,
                       characterCacheBuilder.Build(),
                       pageArray,
                       characterPageViews,
                       charMap,
                       (ConstantBufferBinding)textFS.GetBindingByIdentifier(TEXT_COLOR_SHADER_CB_NAME),
                       maxCharHeight
                       ));
        }
        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();
        }
        public void ShouldCookParametersCorrectly()
        {
            // Define variables and constants
            GeometryCacheBuilder <TestVertex> testVertexCacheBuilder = new GeometryCacheBuilder <TestVertex>();
            int cacheID = (int)typeof(GeometryCacheBuilder <TestVertex>).GetField("cacheID", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(testVertexCacheBuilder);

            TestVertex[] model1Verts =
            {
                new TestVertex(Vector3.ONE * 0f, Vector2.ONE * 0f),
                new TestVertex(Vector3.ONE * 1f, Vector2.ONE * 1f),
                new TestVertex(Vector3.ONE * 2f, Vector2.ONE * 2f),
            };
            TestVertex[] model2Verts =
            {
                new TestVertex(Vector3.ONE * 3f, Vector2.ONE * 3f),
                new TestVertex(Vector3.ONE * 4f, Vector2.ONE * 4f),
                new TestVertex(Vector3.ONE * 5f, Vector2.ONE * 5f),
            };

            uint[] model1Indices =
            {
                0U, 1U, 2U,
                1U, 2U, 0U,
                2U, 0U, 1U
            };
            uint[] model2Indices =
            {
                3U, 4U, 5U,
                4U, 5U, 3U,
                5U, 3U, 4U,
                3U, 5U, 4U
            };

            uint outVBStartIndex, outIBStartIndex, outVBCount, outIBCount;

            // Set up context
            Assert.AreEqual(new ModelHandle(cacheID, 0U), testVertexCacheBuilder.AddModel("SCPC_a", model1Verts, model1Indices));
            Assert.AreEqual(new ModelHandle(cacheID, 1U), testVertexCacheBuilder.AddModel("SCPC_b", model2Verts, model2Indices));

            // Execute
            GeometryCache result = testVertexCacheBuilder.Build();

            // Assert outcome
            Assert.AreEqual(cacheID, result.ID);
            Assert.AreEqual(result, GeometryCache.GetCacheByID(cacheID));

            Assert.AreEqual((uint)(model1Indices.Length + model2Indices.Length), result.IndexBuffer.Length);
            Assert.AreEqual((uint)(model1Verts.Length + model2Verts.Length), result.VertexBuffers[0].Length);
            Assert.AreEqual(2, result.VertexBuffers.Count);
            Assert.AreEqual(ResourceFormat.R32G32B32Float, result.VertexFormats[0]);
            Assert.AreEqual(ResourceFormat.R32G32Float, result.VertexFormats[1]);
            Assert.AreEqual(2U, result.NumModels);
            Assert.AreEqual(6U, result.NumVertices);

            Assert.AreEqual(typeof(VertexBuffer <Vector3>), result.VertexBuffers[0].GetType());
            Assert.AreEqual(typeof(VertexBuffer <Vector2>), result.VertexBuffers[1].GetType());

            Assert.AreEqual("POSITION", result.VertexSemantics[0]);
            Assert.AreEqual("TEXCOORD", result.VertexSemantics[1]);

            result.GetModelBufferValues(0U, out outVBStartIndex, out outIBStartIndex, out outVBCount, out outIBCount);

            Assert.AreEqual(0U, outVBStartIndex);
            Assert.AreEqual(0U, outIBStartIndex);
            Assert.AreEqual(3U, outVBCount);
            Assert.AreEqual(9U, outIBCount);

            result.GetModelBufferValues(1U, out outVBStartIndex, out outIBStartIndex, out outVBCount, out outIBCount);

            Assert.AreEqual(3U, outVBStartIndex);
            Assert.AreEqual(9U, outIBStartIndex);
            Assert.AreEqual(3U, outVBCount);
            Assert.AreEqual(12U, outIBCount);

#if !DEVELOPMENT && !RELEASE
            try {
                result.GetModelBufferValues(2U, out outVBStartIndex, out outIBStartIndex, out outVBCount, out outIBCount);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif

            result.Dispose();
        }