Beispiel #1
0
        private void PerformLayoutAndUpdateDeviceBuffers(int atlasWidth, RgbaByte color)
        {
            Vector2 min = new Vector2(float.MaxValue);
            Vector2 max = new Vector2(float.MinValue);

            _textVertices.Clear();
            foreach (var thing in _textLayout.Stuff)
            {
                var width  = thing.Width;
                var height = thing.Height;
                var region = new Vector4(thing.SourceX, thing.SourceY, width, height) / atlasWidth;
                var origin = new Vector2(thing.DestX, thing.DestY);
                if (origin.X > -100000 && origin.Y > -10000)
                {
                    Vector2 localMax = origin + new Vector2(width, height);
                    min = Vector2.Min(min, origin);
                    max = Vector2.Max(max, localMax);
                }
                _textVertices.Add(new TextVertex(origin + new Vector2(0, height), new Vector2(region.X, region.Y + region.W), color));
                _textVertices.Add(new TextVertex(origin + new Vector2(width, height), new Vector2(region.X + region.Z, region.Y + region.W), color));
                _textVertices.Add(new TextVertex(origin + new Vector2(width, 0), new Vector2(region.X + region.Z, region.Y), color));
                _textVertices.Add(new TextVertex(origin, new Vector2(region.X, region.Y), color));
                _characterCount++;
            }

            Size = new Vector2(max.X - min.X, max.Y - min.Y);

            if (_vb == null)
            {
                _vb = _rc.ResourceFactory.CreateVertexBuffer(TextVertex.SizeInBytes * _textVertices.Count, false);
            }

            _vb.SetVertexData(_textVertices.GetArraySegment(), new VertexDescriptor(TextVertex.SizeInBytes, 3), 0);
            EnsureIndexCapacity(_characterCount);
        }
Beispiel #2
0
        public void Update_MultipleMips_1D()
        {
            if (!GD.Features.Texture1D)
            {
                return;
            }

            Texture tex1D = RF.CreateTexture(TextureDescription.Texture1D(
                                                 100, 5, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));

            for (uint level = 0; level < tex1D.MipLevels; level++)
            {
                MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(tex1D, MapMode.Write, level);
                for (int i = 0; i < writeView.Count; i++)
                {
                    writeView[i] = new RgbaByte((byte)i, (byte)(i * 2), (byte)level, 1);
                }
                GD.Unmap(tex1D, level);
            }

            for (uint level = 0; level < tex1D.MipLevels; level++)
            {
                MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(tex1D, MapMode.Read, level);
                for (int i = 0; i < readView.Count; i++)
                {
                    Assert.Equal(new RgbaByte((byte)i, (byte)(i * 2), (byte)level, 1), readView[i]);
                }
                GD.Unmap(tex1D, level);
            }
        }
        public override void CreateDeviceObjects(RenderContext rc)
        {
            ResourceFactory factory = rc.ResourceFactory;

            _vb = factory.CreateVertexBuffer(
                new VertexPosition[]
            {
                new VertexPosition(new Vector3(-1000, 0, -1000)),
                new VertexPosition(new Vector3(+1000, 0, -1000)),
                new VertexPosition(new Vector3(+1000, 0, +1000)),
                new VertexPosition(new Vector3(-1000, 0, +1000)),
            },
                new VertexDescriptor(VertexPosition.SizeInBytes, VertexPosition.ElementCount),
                false);
            _ib = factory.CreateIndexBuffer(new ushort[] { 0, 1, 2, 0, 2, 3 }, false);

            GridSetInfo.CreateAll(
                factory,
                ShaderHelper.LoadBytecode(factory, "Grid", ShaderStages.Vertex),
                ShaderHelper.LoadBytecode(factory, "Grid", ShaderStages.Fragment),
                out _shaderSet, out _resourceBindings);

            const int gridSize    = 64;
            RgbaByte  borderColor = new RgbaByte(255, 255, 255, 150);

            RgbaByte[] pixels = CreateGridTexturePixels(gridSize, 1, borderColor, new RgbaByte());
            _gridTexture    = factory.CreateTexture(pixels, gridSize, gridSize, PixelFormat.R8_G8_B8_A8_UInt);
            _textureBinding = factory.CreateShaderTextureBinding(_gridTexture);

            _rasterizerState = factory.CreateRasterizerState(FaceCullingMode.None, TriangleFillMode.Solid, true, true);
        }
Beispiel #4
0
 public QuadVertex(Vector2 position, Vector2 size, RgbaByte tint, float rotation)
 {
     Position = position;
     Size     = size;
     Tint     = tint;
     Rotation = rotation;
 }
Beispiel #5
0
        public void Map_ThenRead_MultipleArrayLayers()
        {
            Texture src = RF.CreateTexture(TextureDescription.Texture2D(
                                               10, 10, 1, 10, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));

            for (uint layer = 0; layer < src.ArrayLayers; layer++)
            {
                MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(src, MapMode.Write, layer);
                for (int y = 0; y < src.Height; y++)
                {
                    for (int x = 0; x < src.Width; x++)
                    {
                        writeView[x, y] = new RgbaByte((byte)x, (byte)y, (byte)layer, 1);
                    }
                }
                GD.Unmap(src, layer);
            }

            for (uint layer = 0; layer < src.ArrayLayers; layer++)
            {
                MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(src, MapMode.Read, layer);
                for (int y = 0; y < src.Height; y++)
                {
                    for (int x = 0; x < src.Width; x++)
                    {
                        Assert.Equal(new RgbaByte((byte)x, (byte)y, (byte)layer, 1), readView[x, y]);
                    }
                }
                GD.Unmap(src, layer);
            }
        }
Beispiel #6
0
        public unsafe void Update_WithOffset_2D()
        {
            Texture tex2D = RF.CreateTexture(TextureDescription.Texture2D(
                                                 100, 100, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));

            RgbaByte[] data = new RgbaByte[50 * 30];
            for (uint y = 0; y < 30; y++)
            {
                for (uint x = 0; x < 50; x++)
                {
                    data[y * 50 + x] = new RgbaByte((byte)x, (byte)y, 0, 1);
                }

                fixed(RgbaByte *dataPtr = &data[0])
                {
                    GD.UpdateTexture(
                        tex2D, (IntPtr)dataPtr, (uint)(data.Length * sizeof(RgbaByte)),
                        50, 70, 0,
                        50, 30, 1,
                        0, 0);
                }

                MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(tex2D, MapMode.Read);
                for (int y = 0; y < 30; y++)
                {
                    for (int x = 0; x < 50; x++)
                    {
                        Assert.Equal(new RgbaByte((byte)x, (byte)y, 0, 1), readView[x + 50, y + 70]);
                    }
                }
        }
Beispiel #7
0
        public unsafe void Map_NonZeroMip_3D()
        {
            Texture tex3D = RF.CreateTexture(TextureDescription.Texture3D(
                                                 40, 40, 40, 3, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));

            MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(tex3D, MapMode.Write, 2);

            for (int z = 0; z < 10; z++)
            {
                for (int y = 0; y < 10; y++)
                {
                    for (int x = 0; x < 10; x++)
                    {
                        writeView[x, y, z] = new RgbaByte((byte)x, (byte)y, (byte)z, 1);
                    }
                }
            }
            GD.Unmap(tex3D, 2);

            MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(tex3D, MapMode.Read, 2);

            for (int z = 0; z < 10; z++)
            {
                for (int y = 0; y < 10; y++)
                {
                    for (int x = 0; x < 10; x++)
                    {
                        Assert.Equal(new RgbaByte((byte)x, (byte)y, (byte)z, 1), readView[x, y, z]);
                    }
                }
            }
            GD.Unmap(tex3D, 2);
        }
Beispiel #8
0
        public unsafe void MapWrite_ThenMapRead_3D()
        {
            Texture tex3D = RF.CreateTexture(TextureDescription.Texture3D(
                                                 10, 10, 10, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));

            MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(tex3D, MapMode.Write);

            for (int z = 0; z < tex3D.Depth; z++)
            {
                for (int y = 0; y < tex3D.Height; y++)
                {
                    for (int x = 0; x < tex3D.Width; x++)
                    {
                        writeView[x, y, z] = new RgbaByte((byte)x, (byte)y, (byte)z, 1);
                    }
                }
            }
            GD.Unmap(tex3D);

            MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(tex3D, MapMode.Read, 0);

            for (int z = 0; z < tex3D.Depth; z++)
            {
                for (int y = 0; y < tex3D.Height; y++)
                {
                    for (int x = 0; x < tex3D.Width; x++)
                    {
                        Assert.Equal(new RgbaByte((byte)x, (byte)y, (byte)z, 1), readView[x, y, z]);
                    }
                }
            }
            GD.Unmap(tex3D);
        }
        public void ClearColor(byte r, byte g, byte b, byte a)
        {
            var rgbaByte = new RgbaByte(r, g, b, a);

            CommandList.Begin();
            CommandList.SetFramebuffer(Framebuffer);
            CommandList.SetFullViewports();
            CommandList.ClearColorTarget(0,
                                         new RgbaFloat(rgbaByte.R / 255.0f, rgbaByte.G / 255.0f, rgbaByte.B / 255.0f, rgbaByte.A / 255.0f));
            CommandList.End();

            GraphicsDevice.SubmitCommands(CommandList);
            GraphicsDevice.WaitForIdle();

            Assert.AreEqual(rgbaByte, ReadRenderTargetPixel());
        }
Beispiel #10
0
        public unsafe void Update_NonStaging_3D()
        {
            Texture tex3D = RF.CreateTexture(TextureDescription.Texture3D(
                                                 16, 16, 16, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled));

            RgbaByte[] data = new RgbaByte[16 * 16 * 16];
            for (int z = 0; z < 16; z++)
                for (int y = 0; y < 16; y++)
                {
                    for (int x = 0; x < 16; x++)
                    {
                        int index = (int)(z * tex3D.Width * tex3D.Height + y * tex3D.Height + x);
                        data[index] = new RgbaByte((byte)x, (byte)y, (byte)z, 1);
                    }
                }

            fixed(RgbaByte *dataPtr = data)
            {
                GD.UpdateTexture(tex3D, (IntPtr)dataPtr, (uint)(data.Length * Unsafe.SizeOf <RgbaByte>()),
                                 0, 0, 0,
                                 tex3D.Width, tex3D.Height, tex3D.Depth,
                                 0, 0);
            }

            Texture staging = RF.CreateTexture(TextureDescription.Texture3D(
                                                   16, 16, 16, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.CopyTexture(tex3D, staging);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <RgbaByte> view = GD.Map <RgbaByte>(staging, MapMode.Read);

            for (int z = 0; z < tex3D.Depth; z++)
                for (int y = 0; y < tex3D.Height; y++)
                {
                    for (int x = 0; x < tex3D.Width; x++)
                    {
                        Assert.Equal(new RgbaByte((byte)x, (byte)y, (byte)z, 1), view[x, y, z]);
                    }
                }
}
Beispiel #11
0
        public void Copy_WithOffsets_2D(TextureUsage srcUsage, TextureUsage dstUsage)
        {
            Texture src = RF.CreateTexture(TextureDescription.Texture2D(
                                               100, 100, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, srcUsage));

            Texture dst = RF.CreateTexture(TextureDescription.Texture2D(
                                               100, 100, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, dstUsage));

            RgbaByte[] srcData = new RgbaByte[src.Height * src.Width];
            for (int y = 0; y < src.Height; y++)
            {
                for (int x = 0; x < src.Width; x++)
                {
                    srcData[y * src.Width + x] = new RgbaByte((byte)x, (byte)y, 0, 1);
                }
            }

            GD.UpdateTexture(src, srcData, 0, 0, 0, src.Width, src.Height, 1, 0, 0);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.CopyTexture(
                src,
                50, 50, 0, 0, 0,
                dst,
                10, 10, 0, 0, 0,
                50, 50, 1, 1);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            Texture readback = GetReadback(dst);
            MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(readback, MapMode.Read);

            for (int y = 10; y < 60; y++)
            {
                for (int x = 10; x < 60; x++)
                {
                    Assert.Equal(new RgbaByte((byte)(x + 40), (byte)(y + 40), 0, 1), readView[x, y]);
                }
            }
            GD.Unmap(readback);
        }
Beispiel #12
0
        public void Copy_WitOffsets_2D()
        {
            Texture src = RF.CreateTexture(TextureDescription.Texture2D(
                                               100, 100, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));

            Texture dst = RF.CreateTexture(TextureDescription.Texture2D(
                                               100, 100, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));

            MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(src, MapMode.Write);

            for (int y = 0; y < src.Height; y++)
            {
                for (int x = 0; x < src.Width; x++)
                {
                    writeView[x, y] = new RgbaByte((byte)x, (byte)y, 0, 1);
                }
            }
            GD.Unmap(src);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.CopyTexture(
                src,
                50, 50, 0, 0, 0,
                dst, 10, 10, 0, 0, 0,
                50, 50, 1, 1);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(dst, MapMode.Read);

            for (int y = 10; y < 60; y++)
            {
                for (int x = 10; x < 60; x++)
                {
                    Assert.Equal(new RgbaByte((byte)(x + 40), (byte)(y + 40), 0, 1), readView[x, y]);
                }
            }
            GD.Unmap(dst);
        }
Beispiel #13
0
        private RgbaByte[] CreateGridTexturePixels(int dimensions, int borderPixels, RgbaByte borderColor, RgbaByte backgroundColor)
        {
            RgbaByte[] ret = new RgbaByte[dimensions * dimensions];

            for (int y = 0; y < dimensions; y++)
            {
                for (int x = 0; x < dimensions; x++)
                {
                    if ((y < borderPixels) || (dimensions - 1 - y < borderPixels) ||
                        (x < borderPixels) || (dimensions - 1 - x < borderPixels))
                    {
                        ret[x + (y * dimensions)] = borderColor;
                    }
                    else
                    {
                        ret[x + (y * dimensions)] = backgroundColor;
                    }
                }
            }

            return(ret);
        }
Beispiel #14
0
        public unsafe void Update_ThenMapRead_3D()
        {
            Texture tex3D = RF.CreateTexture(TextureDescription.Texture3D(
                                                 10, 10, 10, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));

            RgbaByte[] data = new RgbaByte[tex3D.Width * tex3D.Height * tex3D.Depth];
            for (int z = 0; z < tex3D.Depth; z++)
            {
                for (int y = 0; y < tex3D.Height; y++)
                {
                    for (int x = 0; x < tex3D.Width; x++)
                    {
                        int index = (int)(z * tex3D.Width * tex3D.Height + y * tex3D.Height + x);
                        data[index] = new RgbaByte((byte)x, (byte)y, (byte)z, 1);
                    }
                }

                fixed(RgbaByte *dataPtr = data)
                {
                    GD.UpdateTexture(tex3D, (IntPtr)dataPtr, (uint)(data.Length * Unsafe.SizeOf <RgbaByte>()),
                                     0, 0, 0,
                                     tex3D.Width, tex3D.Height, tex3D.Depth,
                                     0, 0);
                }

                MappedResourceView <RgbaByte> view = GD.Map <RgbaByte>(tex3D, MapMode.Read, 0);
                for (int z = 0; z < tex3D.Depth; z++)
                {
                    for (int y = 0; y < tex3D.Height; y++)
                    {
                        for (int x = 0; x < tex3D.Width; x++)
                        {
                            Assert.Equal(new RgbaByte((byte)x, (byte)y, (byte)z, 1), view[x, y, z]);
                        }
                    }
                }
                GD.Unmap(tex3D);
        }
Beispiel #15
0
        public void TestPermutation(TypeStruct fieldSet)
        {
            var(shaderInstructions, shaders) = CompileShaderForFieldSet(fieldSet);
            var shaderReflection = new ShaderReflection(shaderInstructions);
            var structure        = shaderReflection.Structures.Where(_ => _.DebugName == fieldSet.DebugName).First();

            CompareStructureLayout(structure, fieldSet);

            var bufferSize = structure.SizeInBytes;

            bufferSize = SpirvUtils.RoundUp(bufferSize, 16);
            var buffer = ResourceFactory.CreateBuffer(new BufferDescription(bufferSize, BufferUsage.UniformBuffer));

            Disposables.Add(buffer);

            var bytes   = new byte[bufferSize];
            var counter = 1;
            var hash    = 0;

            PopulateBuffer(bytes, 0, structure, ref counter, ref hash);
            GraphicsDevice.UpdateBuffer(buffer, 0, bytes);

            //structure.EvaluateLayout();

            //var hlsl = SpirvCompilation.CompileVertexFragment(vertex.SpirvBytes, fragment.SpirvBytes, CrossCompileTarget.HLSL, new CrossCompileOptions());
            //var glsl = SpirvCompilation.CompileVertexFragment(vertex.SpirvBytes, fragment.SpirvBytes, CrossCompileTarget.GLSL, new CrossCompileOptions());
            //var msl = SpirvCompilation.CompileVertexFragment(vertex.SpirvBytes, fragment.SpirvBytes, CrossCompileTarget.MSL, new CrossCompileOptions());
            //var essl = SpirvCompilation.CompileVertexFragment(vertex.SpirvBytes, fragment.SpirvBytes, CrossCompileTarget.ESSL, new CrossCompileOptions());


            var layout = ResourceFactory.CreateResourceLayout(new ResourceLayoutDescription(
                                                                  new ResourceLayoutElementDescription("ModelBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex)));

            Disposables.Add(layout);

            var resourceSet = ResourceFactory.CreateResourceSet(new ResourceSetDescription(layout, buffer));

            Disposables.Add(resourceSet);

            var pd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.Disabled,
                RasterizerStateDescription.Default,
                PrimitiveTopology.PointList,
                new ShaderSetDescription(new[] { new VertexLayoutDescription(new VertexElementDescription[] { }) },
                                         shaders),
                new[] { layout },
                Framebuffer.OutputDescription);
            var pipeline = ResourceFactory.CreateGraphicsPipeline(pd);

            Disposables.Add(pipeline);

            CommandList.Begin();
            CommandList.SetFramebuffer(Framebuffer);
            CommandList.SetPipeline(pipeline);
            CommandList.SetGraphicsResourceSet(0, resourceSet);
            CommandList.Draw(1);
            CommandList.End();

            GraphicsDevice.SubmitCommands(CommandList);
            GraphicsDevice.WaitForIdle();

            var expected = new RgbaByte((byte)(hash % 256), (byte)(hash / 256 % 256), (byte)(hash / 65536 % 256),
                                        (byte)(hash / 16777216 % 256));
            var actual = ReadRenderTargetPixel();

            Assert.AreEqual(expected, actual);
        }
Beispiel #16
0
 public TextVertex(Vector2 position, Vector2 texcoords, int color)
 {
     Position  = position;
     TexCoords = texcoords;
     Color     = new RgbaByte((uint)color);
 }
Beispiel #17
0
        public unsafe void Append(TextAnalyzer analyzer, FontFace font, string text, float fontSize, int atlasWidth, RectangleF drawRect, RgbaByte color)
        {
            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            _textLayout.Stuff.Clear();
            _textFormat.Font = font;
            _textFormat.Size = fontSize;

            analyzer.AppendText(text, _textFormat);
            analyzer.PerformLayout(drawRect.X, drawRect.Y, drawRect.Width, drawRect.Height, _textLayout);
            PerformLayoutAndUpdateDeviceBuffers(atlasWidth, color);
        }
Beispiel #18
0
        public unsafe void Append(TextAnalyzer analyzer, FontFace font, CharBuffer charBuffer, float fontSize, int atlasWidth, RectangleF drawRect, RgbaByte color)
        {
            if (charBuffer.Count == 0)
            {
                return;
            }

            _textLayout.Stuff.Clear();
            _textFormat.Font = font;
            _textFormat.Size = fontSize;

            analyzer.AppendText(charBuffer.Buffer, 0, (int)charBuffer.Count, _textFormat);
            analyzer.PerformLayout(drawRect.X, drawRect.Y, drawRect.Width, drawRect.Height, _textLayout);
            PerformLayoutAndUpdateDeviceBuffers(atlasWidth, color);
        }
Beispiel #19
0
 public WireframeVertex(Vector3 position, RgbaByte color) => (Position, Color) = (position, color);
Beispiel #20
0
 public TextVertex(Vector2 position, Vector2 texcoords, RgbaByte color)
 {
     Position  = position;
     TexCoords = texcoords;
     Color     = color;
 }
Beispiel #21
0
        public unsafe override void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, SceneContext sc)
        {
            ResourceFactory factory = gd.ResourceFactory;

            _vb = factory.CreateBuffer(new BufferDescription(VertexPosition.SizeInBytes * 4, BufferUsage.VertexBuffer));
            cl.UpdateBuffer(_vb, 0, new VertexPosition[]
            {
                new VertexPosition(new Vector3(-1000, 0, -1000)),
                new VertexPosition(new Vector3(+1000, 0, -1000)),
                new VertexPosition(new Vector3(+1000, 0, +1000)),
                new VertexPosition(new Vector3(-1000, 0, +1000)),
            });

            _ib = factory.CreateBuffer(new BufferDescription(6 * 2, BufferUsage.IndexBuffer));
            cl.UpdateBuffer(_ib, 0, new ushort[] { 0, 1, 2, 0, 2, 3 });

            const int gridSize    = 64;
            RgbaByte  borderColor = new RgbaByte(255, 255, 255, 150);

            RgbaByte[] pixels      = CreateGridTexturePixels(gridSize, 1, borderColor, new RgbaByte());
            Texture    gridTexture = factory.CreateTexture(new TextureDescription(gridSize, gridSize, 1, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled));

            fixed(RgbaByte *pixelsPtr = pixels)
            {
                gd.UpdateTexture(gridTexture, (IntPtr)pixelsPtr, pixels.SizeInBytes(), 0, 0, 0, gridSize, gridSize, 1, 0, 0);
            }

            TextureView textureView = factory.CreateTextureView(new TextureViewDescription(gridTexture));

            VertexLayoutDescription[] vertexLayouts = new VertexLayoutDescription[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.Position, VertexElementFormat.Float3))
            };

            Shader gridVS = ShaderHelper.LoadShader(gd, factory, "Grid", ShaderStages.Vertex, "VS");
            Shader gridFS = ShaderHelper.LoadShader(gd, factory, "Grid", ShaderStages.Fragment, "FS");

            ResourceLayout layout = factory.CreateResourceLayout(new ResourceLayoutDescription(
                                                                     new ResourceLayoutElementDescription("Projection", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                     new ResourceLayoutElementDescription("View", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                     new ResourceLayoutElementDescription("GridTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                     new ResourceLayoutElementDescription("GridSampler", ResourceKind.Sampler, ShaderStages.Fragment)));

            GraphicsPipelineDescription pd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleAlphaBlend,
                DepthStencilStateDescription.DepthOnlyLessEqual,
                new RasterizerStateDescription(FaceCullMode.None, PolygonFillMode.Solid, FrontFace.Clockwise, true, true),
                PrimitiveTopology.TriangleList,
                new ShaderSetDescription(vertexLayouts, new[] { gridVS, gridFS }),
                new ResourceLayout[] { layout },
                sc.MainSceneFramebuffer.OutputDescription);

            _pipeline = factory.CreateGraphicsPipeline(ref pd);

            _resourceSet = factory.CreateResourceSet(new ResourceSetDescription(
                                                         layout,
                                                         sc.ProjectionMatrixBuffer,
                                                         sc.ViewMatrixBuffer,
                                                         textureView,
                                                         gd.PointSampler));

            _disposeCollector.Add(_vb, _ib, gridTexture, textureView, gridVS, gridFS, layout, _pipeline, _resourceSet);
        }
Beispiel #22
0
        public unsafe void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, GraphicsSystem sc)
        {
            ResourceFactory disposeFactory = new DisposeCollectorResourceFactory(gd.ResourceFactory, _disposeCollector);

            _vb      = _meshData.CreateVertexBuffer(disposeFactory, cl);
            _vb.Name = _name + "_VB";
            _ib      = _meshData.CreateIndexBuffer(disposeFactory, cl, out _indexCount);
            _ib.Name = _name + "_IB";

            _worldAndInverseBuffer = disposeFactory.CreateBuffer(new BufferDescription(64 * 2, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            if (_materialPropsOwned)
            {
                _materialProps.CreateDeviceObjects(gd, cl, sc);
            }

            if (_textureData != null)
            {
                _texture = StaticResourceCache.GetTexture2D(gd, gd.ResourceFactory, _textureData);
            }
            else
            {
                _texture = disposeFactory.CreateTexture(TextureDescription.Texture2D(1, 1, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled));
                RgbaByte color = RgbaByte.Pink;
                gd.UpdateTexture(_texture, (IntPtr)(&color), 4, 0, 0, 0, 1, 1, 1, 0, 0);
            }

            _textureView = StaticResourceCache.GetTextureView(gd.ResourceFactory, _texture);

            if (_alphaTextureData != null)
            {
                _alphamapTexture = _alphaTextureData.CreateDeviceTexture(gd, disposeFactory);
            }
            else
            {
                _alphamapTexture = StaticResourceCache.GetPinkTexture(gd, gd.ResourceFactory);
            }
            _alphaMapView = StaticResourceCache.GetTextureView(gd.ResourceFactory, _alphamapTexture);

            VertexLayoutDescription[] shadowDepthVertexLayouts = new VertexLayoutDescription[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3),
                    new VertexElementDescription("Normal", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3),
                    new VertexElementDescription("TexCoord", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2))
            };

            (Shader depthVS, Shader depthFS) = StaticResourceCache.GetShaders(gd, gd.ResourceFactory, "ShadowDepth");

            ResourceLayout projViewCombinedLayout = StaticResourceCache.GetResourceLayout(
                gd.ResourceFactory,
                new ResourceLayoutDescription(
                    new ResourceLayoutElementDescription("ViewProjection", ResourceKind.UniformBuffer, ShaderStages.Vertex)));

            ResourceLayout worldLayout = StaticResourceCache.GetResourceLayout(gd.ResourceFactory, new ResourceLayoutDescription(
                                                                                   new ResourceLayoutElementDescription("WorldAndInverse", ResourceKind.UniformBuffer, ShaderStages.Vertex)));

            GraphicsPipelineDescription depthPD = new GraphicsPipelineDescription(
                BlendStateDescription.Empty,
                gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqual : DepthStencilStateDescription.DepthOnlyLessEqual,
                RasterizerStateDescription.Default,
                PrimitiveTopology.TriangleList,
                new ShaderSetDescription(shadowDepthVertexLayouts, new[] { depthVS, depthFS }),
                new ResourceLayout[] { projViewCombinedLayout, worldLayout },
                sc.NearShadowMapFramebuffer.OutputDescription);

            _shadowMapPipeline = StaticResourceCache.GetPipeline(gd.ResourceFactory, ref depthPD);

            _shadowMapResourceSets = CreateShadowMapResourceSets(gd.ResourceFactory, disposeFactory, cl, sc, projViewCombinedLayout, worldLayout);

            VertexLayoutDescription[] mainVertexLayouts = new VertexLayoutDescription[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3),
                    new VertexElementDescription("Normal", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3),
                    new VertexElementDescription("TexCoord", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2))
            };

            (Shader mainVS, Shader mainFS) = StaticResourceCache.GetShaders(gd, gd.ResourceFactory, "ShadowMain");

            ResourceLayout projViewLayout = StaticResourceCache.GetResourceLayout(
                gd.ResourceFactory,
                StaticResourceCache.ProjViewLayoutDescription);

            ResourceLayout mainSharedLayout = StaticResourceCache.GetResourceLayout(gd.ResourceFactory, new ResourceLayoutDescription(
                                                                                        new ResourceLayoutElementDescription("LightViewProjection1", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment),
                                                                                        new ResourceLayoutElementDescription("LightViewProjection2", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment),
                                                                                        new ResourceLayoutElementDescription("LightViewProjection3", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment),
                                                                                        new ResourceLayoutElementDescription("DepthLimits", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment),
                                                                                        new ResourceLayoutElementDescription("LightInfo", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment),
                                                                                        new ResourceLayoutElementDescription("CameraInfo", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment),
                                                                                        new ResourceLayoutElementDescription("PointLights", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment)));

            ResourceLayout mainPerObjectLayout = StaticResourceCache.GetResourceLayout(gd.ResourceFactory, new ResourceLayoutDescription(
                                                                                           new ResourceLayoutElementDescription("WorldAndInverse", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment),
                                                                                           new ResourceLayoutElementDescription("MaterialProperties", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment),
                                                                                           new ResourceLayoutElementDescription("SurfaceTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                                           new ResourceLayoutElementDescription("RegularSampler", ResourceKind.Sampler, ShaderStages.Fragment),
                                                                                           new ResourceLayoutElementDescription("AlphaMap", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                                           new ResourceLayoutElementDescription("AlphaMapSampler", ResourceKind.Sampler, ShaderStages.Fragment),
                                                                                           new ResourceLayoutElementDescription("ShadowMapNear", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                                           new ResourceLayoutElementDescription("ShadowMapMid", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                                           new ResourceLayoutElementDescription("ShadowMapFar", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                                           new ResourceLayoutElementDescription("ShadowMapSampler", ResourceKind.Sampler, ShaderStages.Fragment)));

            ResourceLayout reflectionLayout = StaticResourceCache.GetResourceLayout(gd.ResourceFactory, new ResourceLayoutDescription(
                                                                                        new ResourceLayoutElementDescription("ReflectionMap", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                                        new ResourceLayoutElementDescription("ReflectionSampler", ResourceKind.Sampler, ShaderStages.Fragment),
                                                                                        new ResourceLayoutElementDescription("ReflectionViewProj", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                                        new ResourceLayoutElementDescription("ClipPlaneInfo", ResourceKind.UniformBuffer, ShaderStages.Fragment)));

            GraphicsPipelineDescription mainPD = new GraphicsPipelineDescription(
                _alphamapTexture != null ? BlendStateDescription.SingleAlphaBlend : BlendStateDescription.SingleOverrideBlend,
                gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqual : DepthStencilStateDescription.DepthOnlyLessEqual,
                RasterizerStateDescription.Default,
                PrimitiveTopology.TriangleList,
                new ShaderSetDescription(mainVertexLayouts, new[] { mainVS, mainFS }),
                new ResourceLayout[] { projViewLayout, mainSharedLayout, mainPerObjectLayout, reflectionLayout },
                sc.MainSceneFramebuffer.OutputDescription);

            _pipeline      = StaticResourceCache.GetPipeline(gd.ResourceFactory, ref mainPD);
            _pipeline.Name = "MeshRenderer Main Pipeline";
            mainPD.RasterizerState.CullMode = FaceCullMode.Front;
            mainPD.Outputs     = sc.ReflectionFramebuffer.OutputDescription;
            _pipelineFrontCull = StaticResourceCache.GetPipeline(gd.ResourceFactory, ref mainPD);

            _mainProjViewRS = StaticResourceCache.GetResourceSet(gd.ResourceFactory, new ResourceSetDescription(projViewLayout,
                                                                                                                sc.ProjectionMatrixBuffer,
                                                                                                                sc.ViewMatrixBuffer));

            _mainSharedRS = StaticResourceCache.GetResourceSet(gd.ResourceFactory, new ResourceSetDescription(mainSharedLayout,
                                                                                                              sc.LightViewProjectionBuffer0,
                                                                                                              sc.LightViewProjectionBuffer1,
                                                                                                              sc.LightViewProjectionBuffer2,
                                                                                                              sc.DepthLimitsBuffer,
                                                                                                              sc.LightInfoBuffer,
                                                                                                              sc.CameraInfoBuffer,
                                                                                                              sc.PointLightsBuffer));

            _mainPerObjectRS = disposeFactory.CreateResourceSet(new ResourceSetDescription(mainPerObjectLayout,
                                                                                           _worldAndInverseBuffer,
                                                                                           _materialProps.UniformBuffer,
                                                                                           _textureView,
                                                                                           gd.Aniso4xSampler,
                                                                                           _alphaMapView,
                                                                                           gd.LinearSampler,
                                                                                           sc.NearShadowMapView,
                                                                                           sc.MidShadowMapView,
                                                                                           sc.FarShadowMapView,
                                                                                           gd.PointSampler));

            _reflectionRS = StaticResourceCache.GetResourceSet(gd.ResourceFactory, new ResourceSetDescription(reflectionLayout,
                                                                                                              _alphaMapView, // Doesn't really matter -- just don't bind the actual reflection map since it's being rendered to.
                                                                                                              gd.PointSampler,
                                                                                                              sc.ReflectionViewProjBuffer,
                                                                                                              sc.MirrorClipPlaneBuffer));

            _noReflectionRS = StaticResourceCache.GetResourceSet(gd.ResourceFactory, new ResourceSetDescription(reflectionLayout,
                                                                                                                sc.ReflectionColorView,
                                                                                                                gd.PointSampler,
                                                                                                                sc.ReflectionViewProjBuffer,
                                                                                                                sc.NoClipPlaneBuffer));
        }