Exemple #1
0
        /// <inheritdoc/>
        protected override void OnLoadingContent()
        {
            this.content = ContentManager.Create("Content");

            this.sprite      = content.Load <Sprite>("Sprites/Hexagons");
            this.spriteFont  = content.Load <SpriteFont>("Fonts/SegoeUI");
            this.spriteBatch = SpriteBatch.Create();

            this.blankTexture = Texture2D.Create(1, 1);
            this.blankTexture.SetData(new[] { Color.White });

            this.effect = BasicEffect.Create();

            this.vbuffer = VertexBuffer.Create <VertexPositionColor>(3);
            this.vbuffer.SetData <VertexPositionColor>(new[]
            {
                new VertexPositionColor(new Vector3(0, 1, 0), Color.Red),
                new VertexPositionColor(new Vector3(1, -1, 0), Color.Lime),
                new VertexPositionColor(new Vector3(-1, -1, 0), Color.Blue),
            });

            this.geometryStream = GeometryStream.Create();
            this.geometryStream.Attach(this.vbuffer);

            GC.Collect(2);

            base.OnLoadingContent();
        }
Exemple #2
0
 /// <summary>
 /// Ensures that the control's geometry stream exists.
 /// </summary>
 /// <returns>The control's geometry stream.</returns>
 private GeometryStream EnsureGeometryStream()
 {
     if (geometryStream == null)
     {
         geometryStream = GeometryStream.Create();
         geometryStream.Attach(EnsureVertexBuffer());
     }
     return(geometryStream);
 }
        public void UltravioletGraphics_CanRenderSprites_WhenUsingCustomVertexElementNames()
        {
            var effect            = default(Effect);
            var vertexDeclaration = default(VertexDeclaration);
            var vertexBuffer      = default(VertexBuffer);
            var geometryStream    = default(GeometryStream);

            var result = GivenAnUltravioletApplication()
                         .WithContent(content =>
            {
                effect = content.Load <Effect>("Effects\\NamedVertexElements.vert");

                vertexDeclaration = new VertexDeclaration(new[] {
                    new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0, "my_position"),
                    new VertexElement(sizeof(Single) * 3, VertexElementFormat.Color, VertexElementUsage.Color, 0, "my_color")
                });

                vertexBuffer = VertexBuffer.Create(vertexDeclaration, 3);
                vertexBuffer.SetData(new[]
                {
                    new VertexPositionColor(new Vector3(0, 1, 0), Color.Red),
                    new VertexPositionColor(new Vector3(1, -1, 0), Color.Lime),
                    new VertexPositionColor(new Vector3(-1, -1, 0), Color.Blue),
                });

                geometryStream = GeometryStream.Create();
                geometryStream.Attach(vertexBuffer);
            })
                         .Render(uv =>
            {
                var gfx         = uv.GetGraphics();
                var window      = uv.GetPlatform().Windows.GetPrimary();
                var viewport    = new Viewport(0, 0, window.Compositor.Width, window.Compositor.Height);
                var aspectRatio = viewport.Width / (float)viewport.Height;

                gfx.SetViewport(viewport);

                effect.Parameters["World"].SetValue(Matrix.Identity);
                effect.Parameters["View"].SetValue(Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up));
                effect.Parameters["Projection"].SetValue(Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4f, aspectRatio, 1f, 1000f));
                effect.Parameters["DiffuseColor"].SetValue(Color.White);

                foreach (var pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();

                    gfx.SetRasterizerState(RasterizerState.CullNone);
                    gfx.SetGeometryStream(geometryStream);
                    gfx.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
                }
            });

            TheResultingImage(result)
            .ShouldMatch(@"Resources/Expected/Graphics/UltravioletGraphics_CanRenderSprites_WhenUsingCustomVertexElementNames.png");
        }
Exemple #4
0
        public void UltravioletGraphics_CanRenderATexturedTriangle()
        {
            var effect         = default(BasicEffect);
            var vertexBuffer   = default(VertexBuffer);
            var geometryStream = default(GeometryStream);
            var texture        = default(Texture2D);

            var result = GivenAnUltravioletApplication()
                         .WithContent(content =>
            {
                effect = BasicEffect.Create();

                vertexBuffer = VertexBuffer.Create(VertexPositionTexture.VertexDeclaration, 3);
                vertexBuffer.SetData(new[]
                {
                    new VertexPositionTexture(new Vector3(0, 1, 0), new Vector2(0, 0)),
                    new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 0)),
                    new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1))
                });

                geometryStream = GeometryStream.Create();
                geometryStream.Attach(vertexBuffer);

                texture = content.Load <Texture2D>(@"Textures\Triangle");
            })
                         .Render(uv =>
            {
                var gfx         = uv.GetGraphics();
                var window      = uv.GetPlatform().Windows.GetPrimary();
                var viewport    = new Viewport(0, 0, window.Compositor.Width, window.Compositor.Height);
                var aspectRatio = viewport.Width / (float)viewport.Height;

                gfx.SetViewport(viewport);

                effect.World              = Matrix.Identity;
                effect.View               = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up);
                effect.Projection         = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4f, aspectRatio, 1f, 1000f);
                effect.VertexColorEnabled = false;
                effect.TextureEnabled     = true;
                effect.Texture            = texture;

                foreach (var pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();

                    gfx.SetRasterizerState(RasterizerState.CullNone);
                    gfx.SetGeometryStream(geometryStream);
                    gfx.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
                }
            });

            TheResultingImage(result)
            .ShouldMatch(@"Resources/Expected/Graphics/UltravioletGraphics_CanRenderATexturedTriangle.png");
        }
        /// <summary>
        /// Ensures that the geometry buffers exist and have sufficient size.
        /// </summary>
        private void EnsureBuffers(ref ImDrawDataPtr drawDataPtr)
        {
            var dirty    = false;
            var vtxCount = 0;
            var idxCount = 0;

            for (var i = 0; i < drawDataPtr.CmdListsCount; i++)
            {
                var cmd = drawDataPtr.CmdListsRange[i];
                vtxCount = Math.Max(vtxCount, cmd.VtxBuffer.Size);
                idxCount = Math.Max(idxCount, cmd.IdxBuffer.Size);
            }

            if (vertexBuffer == null || vertexBuffer.VertexCount < vtxCount)
            {
                if (vertexBuffer != null)
                {
                    vertexBuffer.Dispose();
                }

                vertexBuffer = DynamicVertexBuffer.Create(ImGuiVertex.VertexDeclaration, vtxCount);
                dirty        = true;
            }

            if (indexBuffer == null || indexBuffer.IndexCount < idxCount)
            {
                if (indexBuffer != null)
                {
                    indexBuffer.Dispose();
                }

                indexBuffer = DynamicIndexBuffer.Create(IndexBufferElementType.Int16, idxCount);
                dirty       = true;
            }

            if (rasterizerState == null)
            {
                rasterizerState = RasterizerState.Create();
                rasterizerState.ScissorTestEnable = true;
            }

            if (geometryStream == null || dirty)
            {
                this.geometryStream = GeometryStream.Create();
                this.geometryStream.Attach(this.vertexBuffer);
                this.geometryStream.Attach(this.indexBuffer);
            }
        }
Exemple #6
0
        protected override void OnLoadingContent()
        {
            this.effect = BasicEffect.Create();

            this.vbuffer = VertexBuffer.Create <VertexPositionColor>(3);
            this.vbuffer.SetData(new[]
            {
                new VertexPositionColor(new Vector3(0, 1, 0), Color.Red),
                new VertexPositionColor(new Vector3(1, -1, 0), Color.Lime),
                new VertexPositionColor(new Vector3(-1, -1, 0), Color.Blue),
            });

            this.geometryStream = GeometryStream.Create();
            this.geometryStream.Attach(this.vbuffer);

            base.OnLoadingContent();
        }
Exemple #7
0
        protected override void OnLoadingContent()
        {
            this.content = ContentManager.Create("Content");
            LoadContentManifests();

            this.texture = this.content.Load <Texture2D>(GlobalTextureID.Triangle);

            this.effect = BasicEffect.Create();

            this.vbuffer = VertexBuffer.Create <VertexPositionTexture>(3);
            this.vbuffer.SetData(new[]
            {
                new VertexPositionTexture(new Vector3(0, 1, 0), new Vector2(0, 0)),
                new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 0)),
                new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1))
            });

            this.geometryStream = GeometryStream.Create();
            this.geometryStream.Attach(this.vbuffer);

            base.OnLoadingContent();
        }
Exemple #8
0
        /// <summary>
        /// Loads 3D geometry used for testing.
        /// </summary>
        protected void LoadTestGeometry()
        {
            /*
             * vertexBuffer = VertexBuffer.Create<VertexPositionColorTexture>(5);
             * vertexBuffer.SetData(new VertexPositionColorTexture[]
             * {
             *  new VertexPositionColorTexture { Position = new Vector3(-1f,   0f, -1f), Color = Color.Red, TextureCoordinate = new Vector2(1, 0) },
             *  new VertexPositionColorTexture { Position = new Vector3( 1f,   0f, -1f), Color = Color.Lime, TextureCoordinate = new Vector2(0, 1) },
             *  new VertexPositionColorTexture { Position = new Vector3( 1f,   0f,  1f), Color = Color.Blue },
             *  new VertexPositionColorTexture { Position = new Vector3(-1f,   0f,  1f), Color = Color.Yellow },
             *  new VertexPositionColorTexture { Position = new Vector3( 0f, 1.5f,  0f), Color = Color.Magenta, TextureCoordinate = new Vector2(0, 0) },
             * });
             */

            vertexBuffer = VertexBuffer.Create <VertexPositionNormalTexture>(36);
            vertexBuffer.SetData(new VertexPositionNormalTexture[]
            {
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 0f, 1f), Normal = new Vector3(0, -1f, 0)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 0f, -1f), Normal = new Vector3(0, -1f, 0)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 0f, -1f), Normal = new Vector3(0, -1f, 0)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 0f, -1f), Normal = new Vector3(0, -1f, 0)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 0f, 1f), Normal = new Vector3(0, -1f, 0)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 0f, 1f), Normal = new Vector3(0, -1f, 0)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 2f, -1f), Normal = new Vector3(0, 0f, -1f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 2f, -1f), Normal = new Vector3(0, 0f, -1f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 0f, -1f), Normal = new Vector3(0, 0f, -1f)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 0f, -1f), Normal = new Vector3(0, 0f, -1f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 0f, -1f), Normal = new Vector3(0, 0f, -1f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 2f, -1f), Normal = new Vector3(0, 0f, -1f)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 0f, -1f), Normal = new Vector3(1f, 0f, 0f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 2f, 1f), Normal = new Vector3(1f, 0f, 0f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 2f, -1f), Normal = new Vector3(1f, 0f, 0f)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 0f, 1f), Normal = new Vector3(1f, 0f, 0f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 2f, 1f), Normal = new Vector3(1f, 0f, 0f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 0f, -1f), Normal = new Vector3(1f, 0f, 0f)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 0f, 1f), Normal = new Vector3(0, 0f, 1f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 2f, 1f), Normal = new Vector3(0, 0f, 1f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 2f, 1f), Normal = new Vector3(0, 0f, 1f)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 2f, 1f), Normal = new Vector3(0, 0f, 1f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 0f, 1f), Normal = new Vector3(0, 0f, 1f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 0f, 1f), Normal = new Vector3(0, 0f, 1f)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 2f, -1f), Normal = new Vector3(-1f, 0f, 0f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 2f, 1f), Normal = new Vector3(-1f, 0f, 0f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 0f, -1f), Normal = new Vector3(-1f, 0f, 0f)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 0f, -1f), Normal = new Vector3(-1f, 0f, 0f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 2f, 1f), Normal = new Vector3(-1f, 0f, 0f)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 0f, 1f), Normal = new Vector3(-1f, 0f, 0f)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 2f, -1f), Normal = new Vector3(0, 1f, 0)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 2f, -1f), Normal = new Vector3(0, 1f, 0)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 2f, 1f), Normal = new Vector3(0, 1f, 0)
                },

                new VertexPositionNormalTexture {
                    Position = new Vector3(1f, 2f, 1f), Normal = new Vector3(0, 1f, 0)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 2f, 1f), Normal = new Vector3(0, 1f, 0)
                },
                new VertexPositionNormalTexture {
                    Position = new Vector3(-1f, 2f, -1f), Normal = new Vector3(0, 1f, 0)
                },
            });

            //indexBuffer = IndexBuffer.Create(IndexBufferElementType.Int16, 18);
            //indexBuffer.SetData(new Int16[] { 2, 1, 0, 0, 3, 2, 0, 1, 4, 1, 2, 4, 2, 3, 4, 3, 0, 4 });

            geometryStream = GeometryStream.Create();
            geometryStream.Attach(vertexBuffer);
            //geometryStream.Attach(indexBuffer);

            effect = BasicEffect.Create();
            effect.EnableStandardLighting();

            rasterizerStateSolid          = RasterizerState.Create();
            rasterizerStateSolid.CullMode = CullMode.CullCounterClockwiseFace;
            rasterizerStateSolid.FillMode = FillMode.Solid;

            rasterizerStateWireframe          = RasterizerState.Create();
            rasterizerStateWireframe.CullMode = CullMode.CullCounterClockwiseFace;
            rasterizerStateWireframe.FillMode = FillMode.Wireframe;

            texture = content.Load <Texture2D>(@"Textures\Triangle");
        }
Exemple #9
0
        public void UltravioletGraphics_CanRenderAColoredTriangle(ColorEncoding encoding)
        {
            var effect         = default(BasicEffect);
            var vertexBuffer   = default(VertexBuffer);
            var geometryStream = default(GeometryStream);

            var result = GivenAnUltravioletApplication()
                         .WithConfiguration(config =>
            {
                if (encoding == ColorEncoding.Srgb)
                {
                    config.SrgbBuffersEnabled           = true;
                    config.SrgbDefaultForTexture2D      = true;
                    config.SrgbDefaultForRenderBuffer2D = true;
                }
            })
                         .WithContent(content =>
            {
                effect = BasicEffect.Create();

                vertexBuffer = VertexBuffer.Create(VertexPositionColor.VertexDeclaration, 3);
                vertexBuffer.SetData(new[]
                {
                    new VertexPositionColor(new Vector3(0, 1, 0), Color.Red),
                    new VertexPositionColor(new Vector3(1, -1, 0), Color.Lime),
                    new VertexPositionColor(new Vector3(-1, -1, 0), Color.Blue),
                });

                geometryStream = GeometryStream.Create();
                geometryStream.Attach(vertexBuffer);
            })
                         .Render(uv =>
            {
                var gfx         = uv.GetGraphics();
                var window      = uv.GetPlatform().Windows.GetPrimary();
                var viewport    = new Viewport(0, 0, window.Compositor.Width, window.Compositor.Height);
                var aspectRatio = viewport.Width / (float)viewport.Height;

                gfx.SetViewport(viewport);

                effect.World              = Matrix.Identity;
                effect.View               = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up);
                effect.Projection         = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4f, aspectRatio, 1f, 1000f);
                effect.VertexColorEnabled = true;

                foreach (var pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();

                    gfx.SetRasterizerState(RasterizerState.CullNone);
                    gfx.SetGeometryStream(geometryStream);
                    gfx.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
                }
            });

            if (encoding == ColorEncoding.Linear)
            {
                TheResultingImage(result)
                .ShouldMatch(@"Resources/Expected/Graphics/UltravioletGraphics_CanRenderAColoredTriangle.png");
            }
            else
            {
                TheResultingImage(result)
                .ShouldMatch(@"Resources/Expected/Graphics/UltravioletGraphics_CanRenderAColoredTriangle(Srgb).png");
            }
        }
Exemple #10
0
        public void UltravioletGraphics_CanRenderInstancedTriangles()
        {
            var effect     = default(Effect);
            var vbuffer0   = default(VertexBuffer);
            var vbuffer1   = default(VertexBuffer);
            var ibuffer0   = default(IndexBuffer);
            var geomstream = default(GeometryStream);

            const Int32 InstancesX = 48;
            const Int32 InstancesY = 36;

            const Single TriangleWidth  = 10f;
            const Single TriangleHeight = 10f;

            var result = GivenAnUltravioletApplication()
                         .WithContent(content =>
            {
                effect = content.Load <Effect>("Effects\\InstancedRenderingTestEffect");

                vbuffer0 = VertexBuffer.Create(VertexPosition.VertexDeclaration, 3);
                vbuffer0.SetData(new[]
                {
                    new VertexPosition(new Vector3(0, 0, 0)),
                    new VertexPosition(new Vector3(TriangleWidth, 0, 0)),
                    new VertexPosition(new Vector3(0, TriangleHeight, 0))
                });

                var instanceData = new CanRenderInstancedTrianglesData[InstancesX * InstancesY];
                for (int y = 0; y < InstancesY; y++)
                {
                    for (int x = 0; x < InstancesX; x++)
                    {
                        var transform =
                            Matrix.CreateTranslation(x * TriangleWidth, y * TriangleHeight, 0);

                        var color = new Color(
                            Math.Max(0, 255 - 5 * x),
                            Math.Max(0, 255 - 5 * y), 0);

                        instanceData[(y * InstancesX) + x] = new CanRenderInstancedTrianglesData(transform, color);
                    }
                }

                vbuffer1 = VertexBuffer.Create(CanRenderInstancedTrianglesData.VertexDeclaration, instanceData.Length);
                vbuffer1.SetData(instanceData);

                ibuffer0 = IndexBuffer.Create(IndexBufferElementType.Int16, 3);
                ibuffer0.SetData(new Int16[] { 0, 1, 2 });

                geomstream = GeometryStream.Create();
                geomstream.Attach(vbuffer0);
                geomstream.Attach(vbuffer1, 1);
                geomstream.Attach(ibuffer0);
            })
                         .Render(uv =>
            {
                var gfx      = uv.GetGraphics();
                var viewport = gfx.GetViewport();

                var matrixTransform = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, 1);
                effect.Parameters["MatrixTransform"].SetValue(matrixTransform);

                foreach (var pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();

                    gfx.SetRasterizerState(RasterizerState.CullNone);
                    gfx.SetGeometryStream(geomstream);
                    gfx.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 1, InstancesX * InstancesY);
                }
            });

            TheResultingImage(result)
            .ShouldMatch(@"Resources/Expected/Graphics/UltravioletGraphics_CanRenderInstancedTriangles.png");
        }
        /// <inheritdoc/>
        public override unsafe Model Process(ContentManager manager, IContentProcessorMetadata metadata, StlModelDescription input)
        {
            var stlMetadata = metadata.As <StlModelProcessorMetadata>();

            var vertexBuffer = VertexBuffer.Create <StlModelVertex>((input.Triangles?.Count ?? 0) * 3);

            if (input.Triangles != null)
            {
                var facetOffset      = 0;
                var facetSizeInBytes = sizeof(StlModelVertex) * 3;

                var vertices = stackalloc StlModelVertex[3];
                for (var i = 0; i < input.Triangles.Count; i++)
                {
                    var triangle = input.Triangles[i];
                    if (triangle == null)
                    {
                        throw new InvalidDataException(UltravioletStrings.MalformedContentFile);
                    }

                    if (stlMetadata.SwapWindingOrder)
                    {
                        vertices[0] = new StlModelVertex {
                            Position = triangle.Vertex3, Normal = triangle.Normal
                        };
                        vertices[1] = new StlModelVertex {
                            Position = triangle.Vertex2, Normal = triangle.Normal
                        };
                        vertices[2] = new StlModelVertex {
                            Position = triangle.Vertex1, Normal = triangle.Normal
                        };
                    }
                    else
                    {
                        vertices[0] = new StlModelVertex {
                            Position = triangle.Vertex1, Normal = triangle.Normal
                        };
                        vertices[1] = new StlModelVertex {
                            Position = triangle.Vertex2, Normal = triangle.Normal
                        };
                        vertices[2] = new StlModelVertex {
                            Position = triangle.Vertex3, Normal = triangle.Normal
                        };
                    }

                    vertexBuffer.SetRawData((IntPtr)vertices, 0, facetOffset, facetSizeInBytes, SetDataOptions.NoOverwrite);
                    facetOffset += facetSizeInBytes;
                }
            }

            var geometryStream = GeometryStream.Create();

            geometryStream.Attach(vertexBuffer);

            var globalTransform = Matrix.Identity;

            if (stlMetadata.RotationX != 0.0f || stlMetadata.RotationY != 0.0f || stlMetadata.RotationZ != 0.0f || stlMetadata.Scale != 1.0f)
            {
                Matrix.CreateRotationX(stlMetadata.RotationX, out var rotX);
                Matrix.CreateRotationY(stlMetadata.RotationY, out var rotY);
                Matrix.CreateRotationZ(stlMetadata.RotationZ, out var rotZ);
                Matrix.CreateScale(stlMetadata.Scale, out var scale);

                Matrix.Multiply(ref globalTransform, ref rotZ, out globalTransform);
                Matrix.Multiply(ref globalTransform, ref rotX, out globalTransform);
                Matrix.Multiply(ref globalTransform, ref rotY, out globalTransform);
                Matrix.Multiply(ref globalTransform, ref scale, out globalTransform);
            }

            var modelMeshMaterial = stlMetadata.DefaultMaterial ?? new BasicMaterial()
            {
                DiffuseColor = Color.White
            };
            var modelMeshGeometry = new ModelMeshGeometry(PrimitiveType.TriangleList, geometryStream, vertexBuffer.VertexCount, 0, modelMeshMaterial);
            var modelMesh         = new ModelMesh(0, null, new[] { modelMeshGeometry });
            var modelNode         = new ModelNode(0, null, modelMesh, null, globalTransform);
            var modelScene        = new ModelScene(0, input.Name, new[] { modelNode });
            var model             = new Model(manager.Ultraviolet, new[] { modelScene });

            return(model);
        }
        public void BasicEffect_RendersACubeCorrectly(BasicEffectTestParameters parameters)
        {
            void DrawGeometry(IUltravioletGraphics gfx, Effect eff, RasterizerState rasterizerState, DepthStencilState depthStencilState, Int32 count)
            {
                foreach (var pass in eff.CurrentTechnique.Passes)
                {
                    pass.Apply();

                    gfx.SetRasterizerState(rasterizerState);
                    gfx.SetDepthStencilState(depthStencilState);
                    gfx.DrawPrimitives(PrimitiveType.TriangleList, 0, count);
                }
            }

            var effect  = default(BasicEffect);
            var vbuffer = default(VertexBuffer);
            var gstream = default(GeometryStream);

            var rasterizerStateSolid     = default(RasterizerState);
            var rasterizerStateWireframe = default(RasterizerState);

            var result = GivenAnUltravioletApplication()
                         .WithContent(content =>
            {
                rasterizerStateSolid          = RasterizerState.Create();
                rasterizerStateSolid.CullMode = CullMode.CullCounterClockwiseFace;
                rasterizerStateSolid.FillMode = FillMode.Solid;

                rasterizerStateWireframe          = RasterizerState.Create();
                rasterizerStateWireframe.CullMode = CullMode.CullCounterClockwiseFace;
                rasterizerStateWireframe.FillMode = FillMode.Wireframe;

                effect                        = BasicEffect.Create();
                effect.FogEnabled             = parameters.FogEnabled;
                effect.TextureEnabled         = parameters.TextureEnabled;
                effect.Texture                = content.Load <Texture2D>("Textures\\Cube");
                effect.VertexColorEnabled     = parameters.VertexColorEnabled;
                effect.LightingEnabled        = parameters.LightingEnabled;
                effect.PreferPerPixelLighting = parameters.PreferPerPixelLighting;

                if (effect.FogEnabled)
                {
                    effect.FogColor = Color.Black;
                    effect.FogStart = 5f;
                    effect.FogEnd   = 5.5f;
                }

                if (effect.LightingEnabled)
                {
                    effect.EnableStandardLighting();
                }

                vbuffer = VertexBuffer.Create <BasicEffectTestVertex>(36);
                vbuffer.SetData(new BasicEffectTestVertex[]
                {
                    // Bottom face
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 0f, 1f), Normal = new Vector3(0, -1f, 0),
                        TextureCoordinate = new Vector2(0.25f, 0.75f), Color = Color.Red
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 0f, -1f), Normal = new Vector3(0, -1f, 0),
                        TextureCoordinate = new Vector2(0.50f, 0.75f), Color = Color.Red
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 0f, -1f), Normal = new Vector3(0, -1f, 0),
                        TextureCoordinate = new Vector2(0.50f, 1.00f), Color = Color.Red
                    },

                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 0f, -1f), Normal = new Vector3(0, -1f, 0),
                        TextureCoordinate = new Vector2(0.50f, 1.00f), Color = Color.Red
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 0f, 1f), Normal = new Vector3(0, -1f, 0),
                        TextureCoordinate = new Vector2(0.25f, 1.00f), Color = Color.Red
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 0f, 1f), Normal = new Vector3(0, -1f, 0),
                        TextureCoordinate = new Vector2(0.25f, 0.75f), Color = Color.Red
                    },

                    // Forward face
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 2f, -1f), Normal = new Vector3(0, 0f, -1f),
                        TextureCoordinate = new Vector2(0.00f, 0.50f), Color = Color.Cyan
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 2f, -1f), Normal = new Vector3(0, 0f, -1f),
                        TextureCoordinate = new Vector2(0.25f, 0.50f), Color = Color.Cyan
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 0f, -1f), Normal = new Vector3(0, 0f, -1f),
                        TextureCoordinate = new Vector2(0.25f, 0.75f), Color = Color.Cyan
                    },

                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 0f, -1f), Normal = new Vector3(0, 0f, -1f),
                        TextureCoordinate = new Vector2(0.25f, 0.75f), Color = Color.Cyan
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 0f, -1f), Normal = new Vector3(0, 0f, -1f),
                        TextureCoordinate = new Vector2(0.00f, 0.75f), Color = Color.Cyan
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 2f, -1f), Normal = new Vector3(0, 0f, -1f),
                        TextureCoordinate = new Vector2(0.00f, 0.50f), Color = Color.Cyan
                    },

                    // Right face
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 2f, 1f), Normal = new Vector3(1f, 0f, 0f),
                        TextureCoordinate = new Vector2(0.25f, 0.50f), Color = Color.Magenta
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 2f, -1f), Normal = new Vector3(1f, 0f, 0f),
                        TextureCoordinate = new Vector2(0.50f, 0.50f), Color = Color.Magenta
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 0f, -1f), Normal = new Vector3(1f, 0f, 0f),
                        TextureCoordinate = new Vector2(0.50f, 0.75f), Color = Color.Magenta
                    },

                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 0f, -1f), Normal = new Vector3(1f, 0f, 0f),
                        TextureCoordinate = new Vector2(0.50f, 0.75f), Color = Color.Magenta
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 0f, 1f), Normal = new Vector3(1f, 0f, 0f),
                        TextureCoordinate = new Vector2(0.25f, 0.75f), Color = Color.Magenta
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 2f, 1f), Normal = new Vector3(1f, 0f, 0f),
                        TextureCoordinate = new Vector2(0.25f, 0.50f), Color = Color.Magenta
                    },

                    // Backward face
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 2f, 1f), Normal = new Vector3(0, 0f, 1f),
                        TextureCoordinate = new Vector2(0.50f, 0.50f), Color = Color.Yellow
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 2f, 1f), Normal = new Vector3(0, 0f, 1f),
                        TextureCoordinate = new Vector2(0.75f, 0.50f), Color = Color.Yellow
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 0f, 1f), Normal = new Vector3(0, 0f, 1f),
                        TextureCoordinate = new Vector2(0.75f, 0.75f), Color = Color.Yellow
                    },

                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 0f, 1f), Normal = new Vector3(0, 0f, 1f),
                        TextureCoordinate = new Vector2(0.75f, 0.75f), Color = Color.Yellow
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 0f, 1f), Normal = new Vector3(0, 0f, 1f),
                        TextureCoordinate = new Vector2(0.50f, 0.75f), Color = Color.Yellow
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 2f, 1f), Normal = new Vector3(0, 0f, 1f),
                        TextureCoordinate = new Vector2(0.50f, 0.50f), Color = Color.Yellow
                    },

                    // Left face
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 2f, -1f), Normal = new Vector3(-1f, 0f, 0f),
                        TextureCoordinate = new Vector2(0.75f, 0.50f), Color = Color.Blue
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 2f, 1f), Normal = new Vector3(-1f, 0f, 0f),
                        TextureCoordinate = new Vector2(1.00f, 0.50f), Color = Color.Blue
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 0f, 1f), Normal = new Vector3(-1f, 0f, 0f),
                        TextureCoordinate = new Vector2(1.00f, 0.75f), Color = Color.Blue
                    },

                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 0f, 1f), Normal = new Vector3(-1f, 0f, 0f),
                        TextureCoordinate = new Vector2(1.00f, 0.75f), Color = Color.Blue
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 0f, -1f), Normal = new Vector3(-1f, 0f, 0f),
                        TextureCoordinate = new Vector2(0.75f, 0.75f), Color = Color.Blue
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 2f, -1f), Normal = new Vector3(-1f, 0f, 0f),
                        TextureCoordinate = new Vector2(0.75f, 0.50f), Color = Color.Blue
                    },

                    // Top face
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 2f, 1f), Normal = new Vector3(0, 1f, 0),
                        TextureCoordinate = new Vector2(0.25f, 0.25f), Color = Color.Lime
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 2f, -1f), Normal = new Vector3(0, 1f, 0),
                        TextureCoordinate = new Vector2(0.50f, 0.25f), Color = Color.Lime
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 2f, -1f), Normal = new Vector3(0, 1f, 0),
                        TextureCoordinate = new Vector2(0.50f, 0.50f), Color = Color.Lime
                    },

                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 2f, -1f), Normal = new Vector3(0, 1f, 0),
                        TextureCoordinate = new Vector2(0.50f, 0.50f), Color = Color.Lime
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(1f, 2f, 1f), Normal = new Vector3(0, 1f, 0),
                        TextureCoordinate = new Vector2(0.25f, 0.50f), Color = Color.Lime
                    },
                    new BasicEffectTestVertex {
                        Position          = new Vector3(-1f, 2f, 1f), Normal = new Vector3(0, 1f, 0),
                        TextureCoordinate = new Vector2(0.25f, 0.25f), Color = Color.Lime
                    },
                });

                gstream = GeometryStream.Create();
                gstream.Attach(vbuffer);
            })
                         .Render(uv =>
            {
                var gfx         = uv.GetGraphics();
                var window      = uv.GetPlatform().Windows.GetCurrent();
                var aspectRatio = window.DrawableSize.Width / (Single)window.DrawableSize.Height;

                effect.World      = Matrix.CreateRotationY((float)(2.0 * Math.PI * 0.45f));
                effect.View       = Matrix.CreateLookAt(new Vector3(0, 3, 6), new Vector3(0, 1f, 0), Vector3.Up);
                effect.Projection = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4f, aspectRatio, 1f, 1000f);

                gfx.SetGeometryStream(gstream);
                DrawGeometry(gfx, effect, rasterizerStateSolid, DepthStencilState.Default, vbuffer.VertexCount / 3);

                effect.FogEnabled             = false;
                effect.TextureEnabled         = false;
                effect.VertexColorEnabled     = false;
                effect.LightingEnabled        = false;
                effect.PreferPerPixelLighting = false;
                effect.DiffuseColor           = Color.Black;
                DrawGeometry(gfx, effect, rasterizerStateWireframe, DepthStencilState.None, vbuffer.VertexCount / 3);
            });

            TheResultingImage(result).WithinAbsoluteThreshold(32)
            .ShouldMatch($@"Resources/Expected/Graphics/BasicEffect_RendersACubeCorrectly({parameters}).png");
        }