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); }
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); }
public QuadVertex(Vector2 position, Vector2 size, RgbaByte tint, float rotation) { Position = position; Size = size; Tint = tint; Rotation = rotation; }
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); } }
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]); } } }
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); }
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()); }
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]); } } }
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); }
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); }
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); }
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); }
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); }
public TextVertex(Vector2 position, Vector2 texcoords, int color) { Position = position; TexCoords = texcoords; Color = new RgbaByte((uint)color); }
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); }
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); }
public WireframeVertex(Vector3 position, RgbaByte color) => (Position, Color) = (position, color);
public TextVertex(Vector2 position, Vector2 texcoords, RgbaByte color) { Position = position; TexCoords = texcoords; Color = color; }
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); }
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)); }