/// <summary> /// Creates a default D3D11 Texture with forced Shared-Flag /// </summary> /// <param name="device"></param> /// <param name="description"></param> /// <param name="D3D10Dev"> </param> /// <param name="D2DFactory"> </param> public SharedTexture(D2DInteropHandler handler, Texture2DDescription description) { As11Tex = new Texture2D(handler.D3DDevice11, new Texture2DDescription() { ArraySize = description.ArraySize, BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource, CpuAccessFlags = description.CpuAccessFlags, Format = description.Format, Height = description.Height, MipLevels = description.MipLevels, OptionFlags = ResourceOptionFlags.KeyedMutex, SampleDescription = description.SampleDescription, Usage = description.Usage, Width = description.Width }); Mutex11 = new KeyedMutex(As11Tex); AsResource = new SlimDX.DXGI.Resource(As11Tex); As10Tex = handler.D3DDevice10.OpenSharedResource<SlimDX.Direct3D10.Texture2D>(AsResource.SharedHandle); Mutex10 = new KeyedMutex(As10Tex); AsSurface = As10Tex.AsSurface(); As2DTarget = SlimDX.Direct2D.RenderTarget.FromDXGI(handler.D2DFactory, AsSurface, new RenderTargetProperties() { MinimumFeatureLevel = FeatureLevel.Direct3D10, Usage = RenderTargetUsage.None, Type = RenderTargetType.Hardware, PixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Premultiplied) }); }
protected void CreateDeviceCompatibleTexture(int width, int height, IDisposable texture10, out IDisposable texture11, out IDisposable srv11) { var texture = (Texture2D)texture10; var device11 = Sprite.Device; lock (device11) { var dxgiResource = new Resource(texture); SlimDX.Direct3D11.Texture2D tex11; if (PixCompatible) { tex11 = new SlimDX.Direct3D11.Texture2D(device11, new SlimDX.Direct3D11.Texture2DDescription { ArraySize = 1, BindFlags = SlimDX.Direct3D11.BindFlags.ShaderResource | SlimDX.Direct3D11.BindFlags.RenderTarget, CpuAccessFlags = SlimDX.Direct3D11.CpuAccessFlags.None, Format = Format.R8G8B8A8_UNorm, Height = height, Width = width, MipLevels = 1, OptionFlags = SlimDX.Direct3D11.ResourceOptionFlags.Shared, SampleDescription = new SampleDescription(1, 0), Usage = SlimDX.Direct3D11.ResourceUsage.Default }); } else { tex11 = device11.OpenSharedResource <SlimDX.Direct3D11.Texture2D>(dxgiResource.SharedHandle); } srv11 = new ShaderResourceView(device11, tex11); // device11.ImmediateContext.GenerateMips((global::SlimDX.Direct3D11.ShaderResourceView)srv11); texture11 = tex11; dxgiResource.Dispose(); } }
private void CreateCharTable(byte bytePrefix) { var TableDesc = new CharTableDescription(); //Get appropriate texture size int sizeX = (int)(Font.FontSize * 12); sizeX = (int)Math.Pow(2, Math.Ceiling(Math.Log(sizeX, 2))); //Try how many lines are needed: var tl = new TextLayout[256]; int line = 0, xPos = 0, yPos = 0; for (int i = 0; i < 256; ++i) { tl[i] = new TextLayout(ModelEx.FontManager.Instance.WriteFactory, Convert.ToChar(i + (bytePrefix << 8)).ToString(), Font); int charWidth = 2 + (int)Math.Ceiling(tl[i].Metrics.LayoutWidth + tl[i].OverhangMetrics.Left + tl[i].OverhangMetrics.Right); int charHeight = 2 + (int)Math.Ceiling(tl[i].Metrics.LayoutHeight + tl[i].OverhangMetrics.Top + tl[i].OverhangMetrics.Bottom); line = Math.Max(line, charHeight); if (xPos + charWidth >= sizeX) { xPos = 0; yPos += line; line = 0; } xPos += charWidth; } int sizeY = (int)(line + yPos); sizeY = (int)Math.Pow(2, Math.Ceiling(Math.Log(sizeY, 2))); //Create Texture var TexDesc = new Texture2DDescription() { ArraySize = 1, BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, Format = Format.R8G8B8A8_UNorm, Height = sizeY, Width = sizeX, MipLevels = 1, OptionFlags = ResourceOptionFlags.Shared, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; var texture = new Texture2D(ModelEx.FontManager.Instance.D3DDevice10, TexDesc); var rtv = new RenderTargetView(ModelEx.FontManager.Instance.D3DDevice10, texture); ModelEx.FontManager.Instance.D3DDevice10.ClearRenderTargetView(rtv, new SlimDX.Color4(0, 1, 1, 1)); //D3DDevice10.ClearRenderTargetView(rtv, new SlimDX.Color4(1, 0, 0, 0)); Surface surface = texture.AsSurface(); var target = RenderTarget.FromDXGI(ModelEx.FontManager.Instance.D2DFactory, surface, rtp); var color = new SolidColorBrush(target, new SlimDX.Color4(1, 1, 1, 1)); target.BeginDraw(); line = 0; xPos = 0; yPos = 0; //for (int i = 0; i < 256; ++i) for (int i = 0; i < 256; ++i) { //1 additional pixel on each side int charWidth = 2 + (int)Math.Ceiling(tl[i].Metrics.LayoutWidth + tl[i].OverhangMetrics.Left + tl[i].OverhangMetrics.Right); int charHeight = 2 + (int)Math.Ceiling(tl[i].Metrics.LayoutHeight + tl[i].OverhangMetrics.Top + tl[i].OverhangMetrics.Bottom); line = Math.Max(line, charHeight); if (xPos + charWidth >= sizeX) { xPos = 0; yPos += line; line = 0; } var charDesc = new CharDescription(); charDesc.CharSize = new Vector2(tl[i].Metrics.WidthIncludingTrailingWhitespace, tl[i].Metrics.Height); charDesc.OverhangLeft = tl[i].OverhangMetrics.Left + 1; charDesc.OverhangTop = tl[i].OverhangMetrics.Top + 1; //Make XPos + CD.Overhang.Left an integer number in order to draw at integer positions charDesc.OverhangLeft += (float)Math.Ceiling(xPos + charDesc.OverhangLeft) - (xPos + charDesc.OverhangLeft); //Make YPos + CD.Overhang.Top an integer number in order to draw at integer positions charDesc.OverhangTop += (float)Math.Ceiling(yPos + charDesc.OverhangTop) - (yPos + charDesc.OverhangTop); charDesc.OverhangRight = charWidth - charDesc.CharSize.X - charDesc.OverhangLeft; charDesc.OverhangBottom = charHeight - charDesc.CharSize.Y - charDesc.OverhangTop; charDesc.TexCoordsStart = new Vector2(((float)xPos / sizeX), ((float)yPos / sizeY)); charDesc.TexCoordsSize = new Vector2((float)charWidth / sizeX, (float)charHeight / sizeY); charDesc.TableDescription = TableDesc; TableDesc.Chars[i] = charDesc; target.DrawTextLayout(new PointF(xPos + charDesc.OverhangLeft, yPos + charDesc.OverhangTop), tl[i], color); xPos += charWidth; tl[i].Dispose(); } target.EndDraw(); color.Dispose(); //This is a workaround for Windows 8.1 machines. //If these lines would not be present, the shared resource would be empty. //TODO: find a nicer solution using (var ms = new MemoryStream()) Texture2D.ToStream(texture, ImageFileFormat.Bmp, ms); System.Threading.Monitor.Enter(D3DDevice11); var dxgiResource = new SlimDX.DXGI.Resource(texture); SlimDX.Direct3D11.Texture2D Texture11; if (PixCompatible) { Texture11 = new SlimDX.Direct3D11.Texture2D(D3DDevice11, new SlimDX.Direct3D11.Texture2DDescription() { ArraySize = 1, BindFlags = SlimDX.Direct3D11.BindFlags.ShaderResource | SlimDX.Direct3D11.BindFlags.RenderTarget, CpuAccessFlags = SlimDX.Direct3D11.CpuAccessFlags.None, Format = Format.R8G8B8A8_UNorm, Height = sizeY, Width = sizeX, MipLevels = 1, OptionFlags = SlimDX.Direct3D11.ResourceOptionFlags.Shared, SampleDescription = new SampleDescription(1, 0), Usage = SlimDX.Direct3D11.ResourceUsage.Default }); } else { Texture11 = D3DDevice11.OpenSharedResource <SlimDX.Direct3D11.Texture2D>(dxgiResource.SharedHandle); } var srv = new SlimDX.Direct3D11.ShaderResourceView(D3DDevice11, Texture11); TableDesc.Texture = Texture11; TableDesc.SRV = srv; rtv.Dispose(); System.Threading.Monitor.Exit(D3DDevice11); System.Diagnostics.Debug.WriteLine("Created Char Table " + bytePrefix + " in " + sizeX + " x " + sizeY); //System.Threading.Monitor.Enter(D3DDevice11); //SlimDX.Direct3D11.Texture2D.SaveTextureToFile(Sprite.Device.ImmediateContext, Texture11, SlimDX.Direct3D11.ImageFileFormat.Png, Font.FontFamilyName + "Table" + BytePrefix + ".png"); //System.Threading.Monitor.Exit(D3DDevice11); CharTables.Add(bytePrefix, TableDesc); dxgiResource.Dispose(); target.Dispose(); surface.Dispose(); texture.Dispose(); }
/// <summary> /// Helper method to get a shared handle from a Direct3D10 texture /// </summary> /// <param name="texture">The texture to get a shared handle from</param> /// <returns>The shared handle of the texture</returns> private static IntPtr GetSharedHandle(Texture2D texture) { var resource = new SlimDX.DXGI.Resource(texture); IntPtr result = resource.SharedHandle; resource.Dispose(); return result; }
public void Resize() { Viewport vp = this.DeviceManager.Context.Rasterizer.GetViewports()[0]; int width = (int)vp.Width; int height = (int)vp.Height; if (height == 0 || width == 0) { return; } this.TextureSize = new Vector2(width, height); float w = width / 2f, h = height / 2f; List <byte> vertexBytes = new List <byte>(); CGHelper.AddListBuffer(new Vector3(-w, h, 0), vertexBytes); CGHelper.AddListBuffer(new Vector2(0, 0), vertexBytes); CGHelper.AddListBuffer(new Vector3(w, h, 0), vertexBytes); CGHelper.AddListBuffer(new Vector2(1, 0), vertexBytes); CGHelper.AddListBuffer(new Vector3(-w, -h, 0), vertexBytes); CGHelper.AddListBuffer(new Vector2(0, 1), vertexBytes); CGHelper.AddListBuffer(new Vector3(w, h, 0), vertexBytes); CGHelper.AddListBuffer(new Vector2(1, 0), vertexBytes); CGHelper.AddListBuffer(new Vector3(w, -h, 0), vertexBytes); CGHelper.AddListBuffer(new Vector2(1, 1), vertexBytes); CGHelper.AddListBuffer(new Vector3(-w, -h, 0), vertexBytes); CGHelper.AddListBuffer(new Vector2(0, 1), vertexBytes); using (DataStream ds = new DataStream(vertexBytes.ToArray(), true, true)) { BufferDescription bufDesc = new BufferDescription() { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)ds.Length }; if (this.VertexBuffer != null && !this.VertexBuffer.Disposed) { this.VertexBuffer.Dispose(); } this.VertexBuffer = new SlimDX.Direct3D11.Buffer(this.DeviceManager.Device, ds, bufDesc); } this.SpriteProjectionMatrix = Matrix.OrthoLH(width, height, 0, 100); this.spriteViewport = new Viewport() { Width = width, Height = height, MaxZ = 1 }; this.ViewMatrix = Matrix.LookAtLH(new Vector3(0, 0, -1), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); //DirectX11 for texture creation if (this.TextureD3D11 != null && !this.TextureD3D11.Disposed) { this.TextureD3D11.Dispose(); } this.TextureD3D11 = new Texture2D(this.DeviceManager.Device, new Texture2DDescription() { Width = width, Height = height, MipLevels = 1, ArraySize = 1, Format = Format.B8G8R8A8_UNorm, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.KeyedMutex }); //Share DX10 and DX11 texture resources Resource sharedResource = new Resource(this.TextureD3D11); if (this.TextureD3D10 != null && !this.TextureD3D10.Disposed) { this.TextureD3D10.Dispose(); } this.TextureD3D10 = this.DeviceManager.Device10.OpenSharedResource <SlimDX.Direct3D10.Texture2D>(sharedResource.SharedHandle); if (this.MutexD3D10 != null && !this.MutexD3D10.Disposed) { this.MutexD3D10.Dispose(); } if (this.MutexD3D11 != null && !this.MutexD3D11.Disposed) { this.MutexD3D11.Dispose(); } this.MutexD3D10 = new KeyedMutex(this.TextureD3D10); this.MutexD3D11 = new KeyedMutex(this.TextureD3D11); sharedResource.Dispose(); Surface surface = this.TextureD3D10.AsSurface(); RenderTargetProperties rtp = new RenderTargetProperties(); rtp.MinimumFeatureLevel = FeatureLevel.Direct3D10; rtp.Type = RenderTargetType.Hardware; rtp.Usage = RenderTargetUsage.None; rtp.PixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Premultiplied); if (this.DWRenderTarget != null && !this.DWRenderTarget.Disposed) { this.DWRenderTarget.Dispose(); } this.DWRenderTarget = RenderTarget.FromDXGI(this.context.D2DFactory, surface, rtp); surface.Dispose(); if (RenderTargetRecreated != null) { RenderTargetRecreated(this, new EventArgs()); } }