private void UnloadResources() { m_compositeEffect.Dispose(); m_affineTransformEffect.Dispose(); m_ShadowFullScreen.Dispose(); m_Shadow.Dispose(); m_Bitmap1FullScreen.Dispose(); m_Bitmap1.Dispose(); fontFamily.Dispose(); m_textFormat15.Dispose(); m_textFormat10.Dispose(); roundedRecInColor.Dispose(); roundedRecOutColor.Dispose(); m_textBrush.Dispose(); if (m_TitleName != null) { m_TitleName.Dispose(); } if (m_VideoBitmap != null) { m_VideoBitmap.Dispose(); } if (m_CDGBitmap != null) { m_CDGBitmap.Dispose(); } }
public void ReleaseDeviceResources() { Bitmaps.Dispose(); SwapChain.Dispose(); _solidBrush.Dispose(); RenderTarget.Dispose(); }
//清除内存 public void Dispose() { target.Dispose(); factory.Dispose(); rBrush.Dispose(); pBrush.Dispose(); }
private void OnWindowClosing(object sender, CancelEventArgs e) { ClosedEvent.WaitOne(); _selectedColorBrush.Dispose(); _spacingColorBrush.Dispose(); _notMappedColorBrush.Dispose(); _gridColorBrush.Dispose(); }
private void Update(bool forceUpdate = false) { if (isUpdated || forceUpdate) { isUpdated = false; strokeBrush?.Dispose(); strokeBrush = new d2.SolidColorBrush(Renderer.Device, _stroke.ToColor4()); strokeStyle?.Dispose(); strokeStyle = new d2.StrokeStyle(Renderer.Factory, _strokeStyleProp); } }
private void ResetBurshes(RenderContainer renderContainer) { _selectedColorBrush?.Dispose(); _spacingColorBrush?.Dispose(); _notMappedColorBrush?.Dispose(); _gridColorBrush?.Dispose(); RenderTarget target2D = renderContainer.BackBuffer.Target2D; _selectedColorBrush = new SolidColorBrush(target2D, SelectedColor.ToColor4(), null); _spacingColorBrush = new SolidColorBrush(target2D, SpacingColor.ToColor4(), null); _notMappedColorBrush = new SolidColorBrush(target2D, NotMappedColor.ToColor4(), null); _gridColorBrush = new SolidColorBrush(target2D, GridColor.ToColor4(), null); }
public void Dispose() { uiInitialized = false; uiTexture?.Dispose(); uiEffect?.Dispose(); target2d?.Dispose(); uiPrimitive?.Dispose(); textFormat?.Dispose(); textFormatSmall?.Dispose(); textBrush?.Dispose(); blueBrush?.Dispose(); }
public void Dispose() { brush.Dispose(); wrFactory.Dispose(); target.Dispose(); bb.Dispose(); fac.Dispose(); d2dDevice.Dispose(); dxgiFactory2.Dispose(); dxgiAdapter.Dispose(); dxgiDevice2.Dispose(); defDevice.Dispose(); d3device.Dispose(); swapChain.Dispose(); d2dContext.Dispose(); }
public Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, ComObject clientDrawingEffect) { var pathGeometry = new PathGeometry(_d2DFactory); var geometrySink = pathGeometry.Open(); var fontFace = glyphRun.FontFace; if (glyphRun.Indices.Length > 0) fontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices, glyphRun.Advances, glyphRun.Offsets, glyphRun.IsSideways, glyphRun.BidiLevel % 2 != 0, geometrySink); geometrySink.Close(); geometrySink.Dispose(); fontFace.Dispose(); var matrix = new Matrix3x2() { M11 = 1, M12 = 0, M21 = 0, M22 = 1, M31 = baselineOriginX, M32 = baselineOriginY }; var transformedGeometry = new TransformedGeometry(_d2DFactory, pathGeometry, matrix); var brushColor = (Color4)Color.Black; if (clientDrawingEffect != null && clientDrawingEffect is ColorDrawingEffect) brushColor = (clientDrawingEffect as ColorDrawingEffect).Color; var brush = new SolidColorBrush(_renderTarget, brushColor); _renderTarget.DrawGeometry(transformedGeometry, brush); _renderTarget.FillGeometry(transformedGeometry, brush); pathGeometry.Dispose(); transformedGeometry.Dispose(); brush.Dispose(); return SharpDX.Result.Ok; }
protected void DisposeDirectXResources() { PreDestroyDirectXResources(); SharedBrush.Dispose(); BackgroundBrush.Dispose(); ForegroundBrush.Dispose(); CorrectColorBrush.Dispose(); WrongColorBrush.Dispose(); InputTextFormat.Dispose(); ButtonLabelTextFormat.Dispose(); SubtitleTextFormat.Dispose(); CueTextFormat.Dispose(); DwFactory.Dispose(); RenderTarget.Dispose(); RenderTargetView.Dispose(); D2DFactory.Dispose(); SwapChain.Dispose(); D3DDeviceContext.Dispose(); D3DDevice.Dispose(); }
private void Update(bool forceUpdate = false) { if (isUpdated || forceUpdate) { isUpdated = false; geometry?.Dispose(); geometry = new d2.PathGeometry(Renderer.Factory); var s = geometry.Open(); s.BeginFigure(Points[0], d2.FigureBegin.Filled); s.AddLines(Points.Select(v2 => new mi.RawVector2(v2.X, v2.Y)).ToArray()); s.EndFigure(d2.FigureEnd.Closed); s.Close(); strokeBrush?.Dispose(); strokeBrush = new d2.SolidColorBrush(Renderer.Device, _stroke.ToColor4()); fillBrush?.Dispose(); fillBrush = new d2.SolidColorBrush(Renderer.Device, _fill.ToColor4()); } }
static void over() { var inputPath = "Input.png"; var outputPath = "output.png"; // 그래픽을 랜더링할 장비를 추가 - 3D or 2D var defaultDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware, d3d.DeviceCreationFlags.VideoSupport | d3d.DeviceCreationFlags.BgraSupport | d3d.DeviceCreationFlags.None); var d3dDevice = defaultDevice.QueryInterface <d3d.Device1>(); //get a refer to the D3D 11.1 device var dxgiDevice = d3dDevice.QueryInterface <dxgi.Device1>(); //get a refer to the DXGI device var d2dDevice = new d2.Device(dxgiDevice); // DeviceContext를 초기화. D2D 렌더링 타겟이 될 것이고 모든 렌더링 작업을 허용 var d2dContext = new d2.DeviceContext(d2dDevice, d2.DeviceContextOptions.None); var dwFactory = new dw.Factory(); //D2D, WIC 둘 다 지원되는 픽셀 형식 지정 var d2PixelFormat = new d2.PixelFormat(dxgi.Format.R8G8B8A8_UNorm, d2.AlphaMode.Premultiplied); //RGBA형식 사용 var wicPixelFormat = wic.PixelFormat.Format32bppPRGBA; //이미지 로딩 var imagingFactory = new wic.ImagingFactory2(); var decoder = new wic.PngBitmapDecoder(imagingFactory); var inputStream = new wic.WICStream(imagingFactory, inputPath, NativeFileAccess.Read); decoder.Initialize(inputStream, wic.DecodeOptions.CacheOnLoad); //다이렉트2D가 사용할수 있도록 디코딩 var formatConverter = new wic.FormatConverter(imagingFactory); formatConverter.Initialize(decoder.GetFrame(0), wicPixelFormat); //기본 이미지를 D2D이미지로 로드 //var inputBitmap = d2.Bitmap1.FromWicBitmap(d2dContext, formatConverter, new d2.BitmapProperties1(d2PixelFormat)); //이미지 크기 저장 var inputImageSize = formatConverter.Size; var pixelWidth = inputImageSize.Width; var pixelHeight = inputImageSize.Height; //Effect1 : BitpmapSource - 디코딩된 이미지 데이터를 가져오고 BitmapSource 가져오기 var bitmapSourceEffect = new d2.Effects.BitmapSource(d2dContext); bitmapSourceEffect.WicBitmapSource = formatConverter; // Effect 2 : GaussianBlur - bitmapsource에 가우시안블러 효과 적용 var gaussianBlurEffect = new d2.Effects.GaussianBlur(d2dContext); gaussianBlurEffect.SetInput(0, bitmapSourceEffect.Output, true); gaussianBlurEffect.StandardDeviation = 5f; //overlay text setup var textFormat = new dw.TextFormat(dwFactory, "Arial", 15f); //draw a long text to show the automatic line wrapping var textToDraw = "sime ling text..." + "text" + "dddd"; //create the text layout - this imroves the drawing performance for static text // as the glyph positions are precalculated //윤곽선 글꼴 데이터에서 글자 하나의 모양에 대한 기본 단위를 글리프(glyph)라고 한다 var textLayout = new dw.TextLayout(dwFactory, textToDraw, textFormat, 300f, 1000f); SharpDX.Mathematics.Interop.RawColor4 color = new SharpDX.Mathematics.Interop.RawColor4(255, 255, 255, 1); var textBrush = new d2.SolidColorBrush(d2dContext, color); //여기서부터 다시 //render target setup //create the d2d bitmap description using default flags and 96 DPI var d2dBitmapProps = new d2.BitmapProperties1(d2PixelFormat, 96, 96, d2.BitmapOptions.Target | d2.BitmapOptions.CannotDraw); //the render target var d2dRenderTarget = new d2.Bitmap1(d2dContext, new Size2(pixelWidth, pixelHeight), d2dBitmapProps); d2dContext.Target = d2dRenderTarget; //associate bitmap with the d2d context //Drawing //slow preparations - fast drawing d2dContext.BeginDraw(); d2dContext.DrawImage(gaussianBlurEffect, new SharpDX.Mathematics.Interop.RawVector2(100f, 100f)); d2dContext.DrawTextLayout(new SharpDX.Mathematics.Interop.RawVector2(50f, 50f), textLayout, textBrush); d2dContext.EndDraw(); //Image save //delete the output file if it already exists if (System.IO.File.Exists(outputPath)) { System.IO.File.Delete(outputPath); } //use the appropiate overload to write either to tream or to a file var stream = new wic.WICStream(imagingFactory, outputPath, NativeFileAccess.Write); //select the image encoding format HERE var encoder = new wic.PngBitmapEncoder(imagingFactory); encoder.Initialize(stream); var bitmapFrameEncode = new wic.BitmapFrameEncode(encoder); bitmapFrameEncode.Initialize(); bitmapFrameEncode.SetSize(pixelWidth, pixelHeight); bitmapFrameEncode.SetPixelFormat(ref wicPixelFormat); //this is the trick to write d2d1 bitmap to WIC var imageEncoder = new wic.ImageEncoder(imagingFactory, d2dDevice); imageEncoder.WriteFrame(d2dRenderTarget, bitmapFrameEncode, new wic.ImageParameters(d2PixelFormat, 96, 96, 0, 0, pixelWidth, pixelHeight)); bitmapFrameEncode.Commit(); encoder.Commit(); //cleanup //dispose everything and free used resources bitmapFrameEncode.Dispose(); encoder.Dispose(); stream.Dispose(); textBrush.Dispose(); textLayout.Dispose(); textFormat.Dispose(); formatConverter.Dispose(); //gaussianBlurEffect.Dispose(); bitmapSourceEffect.Dispose(); d2dRenderTarget.Dispose(); inputStream.Dispose(); decoder.Dispose(); d2dContext.Dispose(); dwFactory.Dispose(); imagingFactory.Dispose(); d2dDevice.Dispose(); dxgiDevice.Dispose(); d3dDevice.Dispose(); defaultDevice.Dispose(); //save System.Diagnostics.Process.Start(outputPath); }
protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { // This sample should be used along side the help guide educational resource on this topic: // http://www.ninjatrader.com/support/helpGuides/nt8/en-us/?using_sharpdx_for_custom_chart_rendering.htm // Default plotting in base class. Uncomment if indicators holds at least one plot // in this case we would expect NOT to see the SMA plot we have as well in this sample script //base.OnRender(chartControl, chartScale); // 1.1 - SharpDX Vectors and Charting RenderTarget Coordinates // The SharpDX SDK uses "Vector2" objects to describe a two-dimensional point of a device (X and Y coordinates) SharpDX.Vector2 startPoint; SharpDX.Vector2 endPoint; // For our custom script, we need a way to determine the Chart's RenderTarget coordinates to draw our custom shapes // This info can be found within the NinjaTrader.Gui.ChartPanel class. // You can also use various chartScale and chartControl members to calculate values relative to time and price // However, those concepts will not be discussed or used in this sample // Notes: RenderTarget is always the full ChartPanel, so we need to be mindful which sub-ChartPanel we're dealing with // Always use ChartPanel X, Y, W, H - as chartScale and chartControl properties WPF units, so they can be drastically different depending on DPI set startPoint = new SharpDX.Vector2(ChartPanel.X, ChartPanel.Y); endPoint = new SharpDX.Vector2(ChartPanel.X + ChartPanel.W, ChartPanel.Y + ChartPanel.H); // These Vector2 objects are equivalent with WPF System.Windows.Point and can be used interchangeably depending on your requirements // For convenience, NinjaTrader provides a "ToVector2()" extension method to convert from WPF Points to SharpDX.Vector2 SharpDX.Vector2 startPoint1 = new System.Windows.Point(ChartPanel.X, ChartPanel.Y + ChartPanel.H).ToVector2(); SharpDX.Vector2 endPoint1 = new System.Windows.Point(ChartPanel.X + ChartPanel.W, ChartPanel.Y).ToVector2(); // SharpDX.Vector2 objects contain X/Y properties which are helpful to recalculate new properties based on the initial vector float width = endPoint.X - startPoint.X; float height = endPoint.Y - startPoint.Y; // Or you can recalculate a new vector from existing vector objects SharpDX.Vector2 center = (startPoint + endPoint) / 2; // Tip: This check is simply added to prevent the Indicator dialog menu from opening as a user clicks on the chart // The default behavior is to open the Indicator dialog menu if a user double clicks on the indicator // (i.e, the indicator falls within the RenderTarget "hit testing") // You can remove this check if you want the default behavior implemented if (!IsInHitTest) { // 1.2 - SharpDX Brush Resources // RenderTarget commands must use a special brush resource defined in the SharpDX.Direct2D1 namespace // These resources exist just like you will find in the WPF/Windows.System.Media namespace // such as SolidColorBrushes, LienarGraidentBrushes, RadialGradientBrushes, etc. // To begin, we will start with the most basic "Brush" type // Warning: Brush objects must be disposed of after they have been used SharpDX.Direct2D1.Brush areaBrushDx; SharpDX.Direct2D1.Brush smallAreaBrushDx; SharpDX.Direct2D1.Brush textBrushDx; // for convenience, you can simply convert a WPF Brush to a DXBrush using the ToDxBrush() extension method provided by NinjaTrader // This is a common approach if you have a Brush property created e.g., on the UI you wish to use in custom rendering routines areaBrushDx = areaBrush.ToDxBrush(RenderTarget); smallAreaBrushDx = smallAreaBrush.ToDxBrush(RenderTarget); textBrushDx = textBrush.ToDxBrush(RenderTarget); // However - it should be noted that this conversion process can be rather expensive // If you have many brushes being created, and are not tied to WPF resources // You should rather favor creating the SharpDX Brush directly: // Warning: SolidColorBrush objects must be disposed of after they have been used SharpDX.Direct2D1.SolidColorBrush customDXBrush = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.DodgerBlue); // 1.3 - Using The RenderTarget // before executing chart commands, you have the ability to describe how the RenderTarget should render // for example, we can store the existing RenderTarget AntialiasMode mode // then update the AntialiasMode to be the quality of non-text primitives are rendered SharpDX.Direct2D1.AntialiasMode oldAntialiasMode = RenderTarget.AntialiasMode; RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.Aliased; // Note: The code above stores the oldAntialiasMode as a best practices // i.e., if you plan on changing a property of the RenderTarget, you should plan to set it back // This is to make sure your requirements to no interfere with the function of another script // Additionally smoothing has some performance impacts // Once you have defined all the necessary requirements for you object // You can execute a command on the RenderTarget to draw specific shapes // e.g., we can now use the RenderTarget's DrawLine() command to render a line // using the start/end points and areaBrushDx objects defined before RenderTarget.DrawLine(startPoint, endPoint, areaBrushDx, 4); // Since rendering occurs in a sequential fashion, after you have executed a command // you can switch a property of the RenderTarget to meet other requirements // For example, we can draw a second line now which uses a different AntialiasMode // and the changes render on the chart for both lines from the time they received commands RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; RenderTarget.DrawLine(startPoint1, endPoint1, areaBrushDx, 4); // 1.4 - Rendering Custom Shapes // SharpDX namespace consists of several shapes you can use to draw objects more complicated than lines // For example, we can use the RectangleF object to draw a rectangle that covers the entire chart area SharpDX.RectangleF rect = new SharpDX.RectangleF(startPoint.X, startPoint.Y, width, height); // The RenderTarget consists of two commands related to Rectangles. // The FillRectangle() method is used to "Paint" the area of a Rectangle RenderTarget.FillRectangle(rect, areaBrushDx); // and DrawRectangle() is used to "Paint" the outline of a Rectangle RenderTarget.DrawRectangle(rect, customDXBrush, 2); // Another example is an ellipse which can be used to draw circles // The ellipse center point can be used from the Vectors calculated earlier // The width and height an absolute 100 device pixels // To ensure that pixel coordinates work across all DPI devices, we use the NinjaTrader ChartingExteions methods // Which will convert the "100" value from WPF pixels to Device Pixels both vertically and horizontally int ellipseRadiusY = ChartingExtensions.ConvertToVerticalPixels(100, ChartControl.PresentationSource); int ellipseRadiusX = ChartingExtensions.ConvertToHorizontalPixels(100, ChartControl.PresentationSource); SharpDX.Direct2D1.Ellipse ellipse = new SharpDX.Direct2D1.Ellipse(center, ellipseRadiusX, ellipseRadiusY); // 1.5 - Complex Brush Types and Shapes // For this ellipse, we can use one of the more complex brush types "RadialGradientBrush" // Warning: RadialGradientBrush objects must be disposed of after they have been used SharpDX.Direct2D1.RadialGradientBrush radialGradientBrush; // However creating a RadialGradientBrush requires a few more properties than SolidColorBrush // First, you need to define the array gradient stops the brush will eventually use SharpDX.Direct2D1.GradientStop[] gradientStops = new SharpDX.Direct2D1.GradientStop[2]; // With the gradientStops array, we can describe the color and position of the individual gradients gradientStops[0].Color = SharpDX.Color.Goldenrod; gradientStops[0].Position = 0.0f; gradientStops[1].Color = SharpDX.Color.SeaGreen; gradientStops[1].Position = 1.0f; // then declare a GradientStopCollection from our render target that uses the gradientStops array defined just before // Warning: GradientStopCollection objects must be disposed of after they have been used SharpDX.Direct2D1.GradientStopCollection gradientStopCollection = new SharpDX.Direct2D1.GradientStopCollection(RenderTarget, gradientStops); // we also need to tell our RadialGradientBrush to match the size and shape of the ellipse that we will be drawing // for convenience, SharpDX provides a RadialGradientBrushProperties structure to help define these properties SharpDX.Direct2D1.RadialGradientBrushProperties radialGradientBrushProperties = new SharpDX.Direct2D1.RadialGradientBrushProperties { GradientOriginOffset = new SharpDX.Vector2(0, 0), Center = ellipse.Point, RadiusX = ellipse.RadiusY, RadiusY = ellipse.RadiusY }; // we now have everything we need to create a radial gradient brush radialGradientBrush = new SharpDX.Direct2D1.RadialGradientBrush(RenderTarget, radialGradientBrushProperties, gradientStopCollection); // Finally, we can use this radialGradientBrush to "Paint" the area of the ellipse RenderTarget.FillEllipse(ellipse, radialGradientBrush); // 1.6 - Simple Text Rendering // For rendering custom text to the Chart, there are a few ways you can approach depending on your requirements // The most straight forward way is to "borrow" the existing chartControl font provided as a "SimpleFont" class // Using the chartControl LabelFont, your custom object will also change to the user defined properties allowing // your object to match different fonts if defined by user. // The code below will use the chartControl Properties Label Font if it exists, // or fall back to a default property if it cannot obtain that value NinjaTrader.Gui.Tools.SimpleFont simpleFont = chartControl.Properties.LabelFont ?? new NinjaTrader.Gui.Tools.SimpleFont("Arial", 12); // the advantage of using a SimpleFont is they are not only very easy to describe // but there is also a convenience method which can be used to convert the SimpleFont to a SharpDX.DirectWrite.TextFormat used to render to the chart // Warning: TextFormat objects must be disposed of after they have been used SharpDX.DirectWrite.TextFormat textFormat1 = simpleFont.ToDirectWriteTextFormat(); // Once you have the format of the font, you need to describe how the font needs to be laid out // Here we will create a new Vector2() which draws the font according to the to top left corner of the chart (offset by a few pixels) SharpDX.Vector2 upperTextPoint = new SharpDX.Vector2(ChartPanel.X + 10, ChartPanel.Y + 20); // Warning: TextLayout objects must be disposed of after they have been used SharpDX.DirectWrite.TextLayout textLayout1 = new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Globals.DirectWriteFactory, NinjaTrader.Custom.Resource.SampleCustomPlotUpperLeftCorner, textFormat1, ChartPanel.X + ChartPanel.W, textFormat1.FontSize); // With the format and layout of the text completed, we can now render the font to the chart RenderTarget.DrawTextLayout(upperTextPoint, textLayout1, textBrushDx, SharpDX.Direct2D1.DrawTextOptions.NoSnap); // 1.7 - Advanced Text Rendering // Font formatting and text layouts can get as complex as you need them to be // This example shows how to use a complete custom font unrelated to the existing user-defined chart control settings // Warning: TextLayout and TextFormat objects must be disposed of after they have been used SharpDX.DirectWrite.TextFormat textFormat2 = new SharpDX.DirectWrite.TextFormat(NinjaTrader.Core.Globals.DirectWriteFactory, "Century Gothic", FontWeight.Bold, FontStyle.Italic, 32f); SharpDX.DirectWrite.TextLayout textLayout2 = new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Globals.DirectWriteFactory, NinjaTrader.Custom.Resource.SampleCustomPlotLowerRightCorner, textFormat2, 400, textFormat1.FontSize); // the textLayout object provides a way to measure the described font through a "Metrics" object // This allows you to create new vectors on the chart which are entirely dependent on the "text" that is being rendered // For example, we can create a rectangle that surrounds our font based off the textLayout which would dynamically change if the text used in the layout changed dynamically SharpDX.Vector2 lowerTextPoint = new SharpDX.Vector2(ChartPanel.W - textLayout2.Metrics.Width - 5, ChartPanel.Y + (ChartPanel.H - textLayout2.Metrics.Height)); SharpDX.RectangleF rect1 = new SharpDX.RectangleF(lowerTextPoint.X, lowerTextPoint.Y, textLayout2.Metrics.Width, textLayout2.Metrics.Height); // We can draw the Rectangle based on the TextLayout used above RenderTarget.FillRectangle(rect1, smallAreaBrushDx); RenderTarget.DrawRectangle(rect1, smallAreaBrushDx, 2); // And render the advanced text layout using the DrawTextLayout() method // Note: When drawing the same text repeatedly, using the DrawTextLayout() method is more efficient than using the DrawText() // because the text doesn't need to be formatted and the layout processed with each call RenderTarget.DrawTextLayout(lowerTextPoint, textLayout2, textBrushDx, SharpDX.Direct2D1.DrawTextOptions.NoSnap); // 1.8 - Cleanup // This concludes all of the rendering concepts used in the sample // However - there are some final clean up processes we should always provided before we are done // If changed, do not forget to set the AntialiasMode back to the default value as described above as a best practice RenderTarget.AntialiasMode = oldAntialiasMode; // We also need to make sure to dispose of every device dependent resource on each render pass // Failure to dispose of these resources will eventually result in unnecessary amounts of memory being used on the chart // Although the effects might not be obvious as first, if you see issues related to memory increasing over time // Objects such as these should be inspected first areaBrushDx.Dispose(); customDXBrush.Dispose(); gradientStopCollection.Dispose(); radialGradientBrush.Dispose(); smallAreaBrushDx.Dispose(); textBrushDx.Dispose(); textFormat1.Dispose(); textFormat2.Dispose(); textLayout1.Dispose(); textLayout2.Dispose(); } }
public Result DrawUnderline(object clientDrawingContext, float baselineOriginX, float baselineOriginY, ref Underline underline, ComObject clientDrawingEffect) { var rect = new SharpDX.RectangleF(0, underline.Offset, underline.Width, underline.Offset + underline.Thickness); var rectangleGeometry = new RectangleGeometry(_d2DFactory, rect); var matrix = new Matrix3x2() { M11 = 1, M12 = 0, M21 = 0, M22 = 1, M31 = baselineOriginX, M32 = baselineOriginY }; var transformedGeometry = new TransformedGeometry(_d2DFactory, rectangleGeometry, matrix); var brushColor = new Color4(1, 0, 0, 0); if (clientDrawingEffect != null && clientDrawingEffect is ColorDrawingEffect) brushColor = (clientDrawingEffect as ColorDrawingEffect).Color; var brush = new SolidColorBrush(_renderTarget, brushColor); _renderTarget.DrawGeometry(transformedGeometry, brush); _renderTarget.FillGeometry(transformedGeometry, brush); rectangleGeometry.Dispose(); transformedGeometry.Dispose(); brush.Dispose(); return SharpDX.Result.Ok; }
public void EndDraw() { if (_sbObj.IsFinished || _timing.Offset < _sbObj.MinTime || _sbObj.F.RealTime <= 0) { if (_flag) { _sbObj.ResetRealTime(); _flag = false; } return; } _flag = true; if (_sbObj is AnimatedObject ani && _timing.Offset >= ani.MinTime && _timing.Offset <= ani.MaxTime) { int imgIndex; if (ani.Loop) { imgIndex = (int)((_timing.Offset - ani.MinTime) / ani.Delay % ani.Times); } else { imgIndex = (int)((_timing.Offset - ani.MinTime) / ani.Delay); if (imgIndex >= ani.Times) { imgIndex = ani.Times - 1; } } if (imgIndex != ani.PrevIndex) { ani.PrevIndex = imgIndex; ani.Texture = ani.TextureList[imgIndex]; } } var translateMtx = Matrix3x2.Translation(-_sbObj.X.RealTime, -_sbObj.Y.RealTime); var scaleMtx = Matrix3x2.Scaling((_sbObj.UseH ? -1 : 1) * _sbObj.Vx.RealTime, (_sbObj.UseV ? -1 : 1) * _sbObj.Vy.RealTime); var rotateMtx = Matrix3x2.Rotation(_sbObj.Rad.RealTime); var negTranslateMtx = Matrix3x2.Translation(_sbObj.X.RealTime, _sbObj.Y.RealTime); _target.Transform = translateMtx * scaleMtx * rotateMtx * negTranslateMtx; float rectL = _sbObj.Rect.RealTime.Left - _sbObj.OriginOffsetX - (_sbObj.UseH ? 2 * (_sbObj.Width / 2 - _sbObj.OriginOffsetX) : 0); float rectT = _sbObj.Rect.RealTime.Top - _sbObj.OriginOffsetY - (_sbObj.UseV ? 2 * (_sbObj.Height / 2 - _sbObj.OriginOffsetY) : 0); float rectW = _sbObj.Rect.RealTime.Right - _sbObj.Rect.RealTime.Left; float rectH = _sbObj.Rect.RealTime.Bottom - _sbObj.Rect.RealTime.Top; var realRect = new RectangleF(rectL, rectT, rectW, rectH); if (_sbObj.Texture != null) { if (_sbObj.R.RealTime != 255 || _sbObj.G.RealTime != 255 || _sbObj.B.RealTime != 255) { //JUST FAKE THING var sb = new D2D.SolidColorBrush(_target, new Mathe.RawColor4(_sbObj.R.RealTime / 255f, _sbObj.G.RealTime / 255f, _sbObj.B.RealTime / 255f, _sbObj.F.RealTime)); _target.FillOpacityMask(_sbObj.Texture, sb, D2D.OpacityMaskContent.Graphics, realRect, null); sb.Dispose(); sb = null; } else { _target.DrawBitmap(_sbObj.Texture, realRect, _sbObj.F.RealTime, D2D.BitmapInterpolationMode.Linear); } } #if DEBUG //_target.DrawRectangle(realRect, _redBrush, 1); #endif _target.Transform = new Matrix3x2(1, 0, 0, 1, 0, 0); }
public override void Dispose() { tFormat?.Dispose(); foregroundBrush?.Dispose(); Font?.Dispose(); }
public void Destroy() => _brush.Dispose();
internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition) { if (string.IsNullOrEmpty(text)) return new CCTexture2D(); int imageWidth; int imageHeight; var textDef = textDefinition; var contentScaleFactorWidth = CCLabel.DefaultTexelToContentSizeRatios.Width; var contentScaleFactorHeight = CCLabel.DefaultTexelToContentSizeRatios.Height; textDef.FontSize *= contentScaleFactorWidth; textDef.Dimensions.Width *= contentScaleFactorWidth; textDef.Dimensions.Height *= contentScaleFactorHeight; var font = CreateFont(textDef.FontName, textDef.FontSize); if (font == null) { CCLog.Log("Can not create font {0} with size {1}.", textDef.FontName, textDef.FontSize); return new CCTexture2D(); } var _currentFontSizeEm = textDef.FontSize; var _currentDIP = ConvertPointSizeToDIP(_currentFontSizeEm); // color var foregroundColor = Color4.White; // alignment var horizontalAlignment = textDef.Alignment; var verticleAlignement = textDef.LineAlignment; var textAlign = (CCTextAlignment.Right == horizontalAlignment) ? TextAlignment.Trailing : (CCTextAlignment.Center == horizontalAlignment) ? TextAlignment.Center : TextAlignment.Leading; var paragraphAlign = (CCVerticalTextAlignment.Bottom == vertAlignment) ? ParagraphAlignment.Far : (CCVerticalTextAlignment.Center == vertAlignment) ? ParagraphAlignment.Center : ParagraphAlignment.Near; // LineBreak var lineBreak = (CCLabelLineBreak.Character == textDef.LineBreak) ? WordWrapping.Wrap : (CCLabelLineBreak.Word == textDef.LineBreak) ? WordWrapping.Wrap : WordWrapping.NoWrap; // LineBreak // TODO: Find a way to specify the type of line breaking if possible. var dimensions = new CCSize(textDef.Dimensions.Width, textDef.Dimensions.Height); var layoutAvailable = true; if (dimensions.Width <= 0) { dimensions.Width = 8388608; layoutAvailable = false; } if (dimensions.Height <= 0) { dimensions.Height = 8388608; layoutAvailable = false; } var fontName = font.FontFamily.FamilyNames.GetString(0); var textFormat = new TextFormat(FactoryDWrite, fontName, _currentFontCollection, FontWeight.Regular, FontStyle.Normal, FontStretch.Normal, _currentDIP); textFormat.TextAlignment = textAlign; textFormat.ParagraphAlignment = paragraphAlign; var textLayout = new TextLayout(FactoryDWrite, text, textFormat, dimensions.Width, dimensions.Height); var boundingRect = new RectangleF(); // Loop through all the lines so we can find our drawing offsets var textMetrics = textLayout.Metrics; var lineCount = textMetrics.LineCount; // early out if something went wrong somewhere and nothing is to be drawn if (lineCount == 0) return new CCTexture2D(); // Fill out the bounding rect width and height so we can calculate the yOffset later if needed boundingRect.X = 0; boundingRect.Y = 0; boundingRect.Width = textMetrics.Width; boundingRect.Height = textMetrics.Height; if (!layoutAvailable) { if (dimensions.Width == 8388608) { dimensions.Width = boundingRect.Width; } if (dimensions.Height == 8388608) { dimensions.Height = boundingRect.Height; } } imageWidth = (int)dimensions.Width; imageHeight = (int)dimensions.Height; // Recreate our layout based on calculated dimensions so that we can draw the text correctly // in our image when Alignment is not Left. if (textAlign != TextAlignment.Leading) { textLayout.MaxWidth = dimensions.Width; textLayout.MaxHeight = dimensions.Height; } // Line alignment var yOffset = (CCVerticalTextAlignment.Bottom == verticleAlignement || boundingRect.Bottom >= dimensions.Height) ? dimensions.Height - boundingRect.Bottom // align to bottom : (CCVerticalTextAlignment.Top == verticleAlignement) ? 0 // align to top : (imageHeight - boundingRect.Bottom) * 0.5f; // align to center SharpDX.WIC.Bitmap sharpBitmap = null; WicRenderTarget sharpRenderTarget = null; SolidColorBrush solidBrush = null; try { // Select our pixel format var pixelFormat = SharpDX.WIC.PixelFormat.Format32bppPRGBA; // create our backing bitmap sharpBitmap = new SharpDX.WIC.Bitmap(FactoryImaging, imageWidth, imageHeight, pixelFormat, BitmapCreateCacheOption.CacheOnLoad); // Create the render target that we will draw to sharpRenderTarget = new WicRenderTarget(Factory2D, sharpBitmap, new RenderTargetProperties()); // Create our brush to actually draw with solidBrush = new SolidColorBrush(sharpRenderTarget, foregroundColor); // Begin the drawing sharpRenderTarget.BeginDraw(); if (textDefinition.isShouldAntialias) sharpRenderTarget.AntialiasMode = AntialiasMode.Aliased; // Clear it sharpRenderTarget.Clear(TransparentColor); // Draw the text to the bitmap sharpRenderTarget.DrawTextLayout(new Vector2(boundingRect.X, yOffset), textLayout, solidBrush); // End our drawing which will commit the rendertarget to the bitmap sharpRenderTarget.EndDraw(); // Debugging purposes //var s = "Label4"; //SaveToFile(@"C:\Xamarin\" + s + ".png", _bitmap, _renderTarget); // The following code creates a .png stream in memory of our Bitmap and uses it to create our Textue2D Texture2D tex = null; using (var memStream = new MemoryStream()) { using (var encoder = new PngBitmapEncoder(FactoryImaging, memStream)) using (var frameEncoder = new BitmapFrameEncode(encoder)) { frameEncoder.Initialize(); frameEncoder.WriteSource(sharpBitmap); frameEncoder.Commit(); encoder.Commit(); } // Create the Texture2D from the png stream tex = Texture2D.FromStream(CCDrawManager.SharedDrawManager.XnaGraphicsDevice, memStream); } // Return our new CCTexture2D created from the Texture2D which will have our text drawn on it. return new CCTexture2D(tex); } catch (Exception exc) { CCLog.Log("CCLabel-Windows: Unable to create the backing image of our text. Message: {0}", exc.StackTrace); } finally { if (sharpBitmap != null) { sharpBitmap.Dispose(); sharpBitmap = null; } if (sharpRenderTarget != null) { sharpRenderTarget.Dispose(); sharpRenderTarget = null; } if (solidBrush != null) { solidBrush.Dispose(); solidBrush = null; } if (textFormat != null) { textFormat.Dispose(); textFormat = null; } if (textLayout != null) { textLayout.Dispose(); textLayout = null; } } // If we have reached here then something has gone wrong. return new CCTexture2D(); }
public Result DrawStrikethrough(object clientDrawingContext, float baselineOriginX, float baselineOriginY, ref Strikethrough strikethrough, ComObject clientDrawingEffect) { var rect = new SharpDX.RectangleF(0, strikethrough.Offset, strikethrough.Width, strikethrough.Offset + strikethrough.Thickness); var rectangleGeometry = new RectangleGeometry(_d2DFactory, rect); var matrix = new Matrix3x2() { M11 = 1, M12 = 0, M21 = 0, M22 = 1, M31 = baselineOriginX, M32 = baselineOriginY }; var transformedGeometry = new TransformedGeometry(_d2DFactory, rectangleGeometry, matrix); var brushColor = (Color4)Color.Black; if (clientDrawingEffect != null && clientDrawingEffect is ColorDrawingEffect) brushColor = (Color4)(clientDrawingEffect as ColorDrawingEffect).Color; var brush = new SolidColorBrush(_renderTarget, brushColor); _renderTarget.DrawGeometry(transformedGeometry, brush); _renderTarget.FillGeometry(transformedGeometry, brush); rectangleGeometry.Dispose(); transformedGeometry.Dispose(); brush.Dispose(); return Result.Ok; }
public void DisplayName(string name) { var brush = new SolidColorBrush(renderTarget, Color4.White); var layoutRect = new SharpDX.RectangleF(0, 0, bounds.Width, bounds.Height); renderTarget.BeginDraw(); renderTarget.Clear(Color4.Black); renderTarget.DrawRectangle(new SharpDX.RectangleF(0, 0, bounds.Width, bounds.Height), brush, 10f); renderTarget.DrawText(name, textFormat, layoutRect, solidColorBrush); //int nx = 4; //int ny = 4; //for (int i = 0; i < nx - 1; i++) // for (int j = 0; j < ny - 1; j++) // { // float x = (float)bounds.Width / (float)nx * (i + 1); // float y = (float)bounds.Height / (float)ny * (j + 1); // const int w = 10; // renderTarget.DrawLine(new Vector2(x - w, y), new Vector2(x + w, y), brush, 1); // renderTarget.DrawLine(new Vector2(x, y - w), new Vector2(x, y + w), brush, 1); // } int nx = 4; int ny = 4; for (int i = 0; i < nx - 1; i++) { float x = (float)bounds.Width / (float)nx * (i + 1); renderTarget.DrawLine(new Vector2(x, 0), new Vector2(x, bounds.Height), brush, 1); } for (int i = 0; i < ny - 1; i++) { float y = (float)bounds.Height / (float)ny * (i + 1); renderTarget.DrawLine(new Vector2(0, y), new Vector2(bounds.Width, y), brush, 1); } renderTarget.EndDraw(); brush.Dispose(); }
public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars) { Bars bars = chartBars.Bars; if (chartBars.FromIndex > 0) { chartBars.FromIndex--; } SharpDX.Direct2D1.PathGeometry lineGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); AntialiasMode oldAliasMode = RenderTarget.AntialiasMode; GeometrySink sink = lineGeometry.Open(); sink.BeginFigure(new Vector2(chartControl.GetXByBarIndex(chartBars, chartBars.FromIndex > -1 ? chartBars.FromIndex : 0), chartScale.GetYByValue(bars.GetClose(chartBars.FromIndex > -1 ? chartBars.FromIndex : 0))), FigureBegin.Filled); for (int idx = chartBars.FromIndex + 1; idx <= chartBars.ToIndex; idx++) { double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); float x = chartControl.GetXByBarIndex(chartBars, idx); sink.AddLine(new Vector2(x, close)); } sink.EndFigure(FigureEnd.Open); sink.Close(); RenderTarget.AntialiasMode = AntialiasMode.PerPrimitive; RenderTarget.DrawGeometry(lineGeometry, UpBrushDX, (float)Math.Max(1, chartBars.Properties.ChartStyle.BarWidth)); lineGeometry.Dispose(); SharpDX.Direct2D1.SolidColorBrush fillOutline = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.Transparent); SharpDX.Direct2D1.PathGeometry fillGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); GeometrySink fillSink = fillGeometry.Open(); fillSink.BeginFigure(new Vector2(chartControl.GetXByBarIndex(chartBars, chartBars.FromIndex > -1 ? chartBars.FromIndex : 0), chartScale.GetYByValue(chartScale.MinValue)), FigureBegin.Filled); float fillx = float.NaN; for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++) { double closeValue = bars.GetClose(idx); float close = chartScale.GetYByValue(closeValue); fillx = chartControl.GetXByBarIndex(chartBars, idx); fillSink.AddLine(new Vector2(fillx, close)); } if (!double.IsNaN(fillx)) { fillSink.AddLine(new Vector2(fillx, chartScale.GetYByValue(chartScale.MinValue))); } fillSink.EndFigure(FigureEnd.Open); fillSink.Close(); DownBrushDX.Opacity = Opacity / 100f; if (!(DownBrushDX is SharpDX.Direct2D1.SolidColorBrush)) { TransformBrush(DownBrushDX, new RectangleF(0, 0, (float)chartScale.Width, (float)chartScale.Height)); } RenderTarget.FillGeometry(fillGeometry, DownBrushDX); RenderTarget.DrawGeometry(fillGeometry, fillOutline, (float)chartBars.Properties.ChartStyle.BarWidth); fillOutline.Dispose(); RenderTarget.AntialiasMode = oldAliasMode; fillGeometry.Dispose(); }
public void Run() { var form = new RenderForm("2d and 3d combined...it's like magic"); form.KeyDown += (sender, args) => { if (args.KeyCode == Keys.Escape) form.Close(); }; // DirectX DXGI 1.1 factory var factory1 = new Factory1(); // The 1st graphics adapter var adapter1 = factory1.GetAdapter1(0); // --------------------------------------------------------------------------------------------- // Setup direct 3d version 11. It's context will be used to combine the two elements // --------------------------------------------------------------------------------------------- var description = new SwapChainDescription { BufferCount = 1, ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm), IsWindowed = true, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput, Flags = SwapChainFlags.AllowModeSwitch }; Device11 device11; SwapChain swapChain; Device11.CreateWithSwapChain(adapter1, DeviceCreationFlags.None, description, out device11, out swapChain); // create a view of our render target, which is the backbuffer of the swap chain we just created RenderTargetView renderTargetView; using (var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0)) renderTargetView = new RenderTargetView(device11, resource); // setting a viewport is required if you want to actually see anything var context = device11.ImmediateContext; var viewport = new Viewport(0.0f, 0.0f, form.ClientSize.Width, form.ClientSize.Height); context.OutputMerger.SetTargets(renderTargetView); context.Rasterizer.SetViewports(viewport); // // Create the DirectX11 texture2D. This texture will be shared with the DirectX10 device. // // The DirectX10 device will be used to render text onto this texture. // DirectX11 will then draw this texture (blended) onto the screen. // The KeyedMutex flag is required in order to share this resource between the two devices. var textureD3D11 = new Texture2D(device11, new Texture2DDescription { Width = form.ClientSize.Width, Height = form.ClientSize.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.SharedKeyedmutex }); // --------------------------------------------------------------------------------------------- // Setup a direct 3d version 10.1 adapter // --------------------------------------------------------------------------------------------- var device10 = new Device10(adapter1, SharpDX.Direct3D10.DeviceCreationFlags.BgraSupport, FeatureLevel.Level_10_0); // --------------------------------------------------------------------------------------------- // Setup Direct 2d // --------------------------------------------------------------------------------------------- // Direct2D Factory var factory2D = new SharpDX.Direct2D1.Factory(FactoryType.SingleThreaded, DebugLevel.Information); // Here we bind the texture we've created on our direct3d11 device through the direct3d10 // to the direct 2d render target.... var sharedResource = textureD3D11.QueryInterface<SharpDX.DXGI.Resource>(); var textureD3D10 = device10.OpenSharedResource<SharpDX.Direct3D10.Texture2D>(sharedResource.SharedHandle); var surface = textureD3D10.AsSurface(); var rtp = new RenderTargetProperties { MinLevel = SharpDX.Direct2D1.FeatureLevel.Level_10, Type = RenderTargetType.Hardware, PixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Premultiplied) }; var renderTarget2D = new RenderTarget(factory2D, surface, rtp); var solidColorBrush = new SolidColorBrush(renderTarget2D, Colors.Red); // --------------------------------------------------------------------------------------------------- // Setup the rendering data // --------------------------------------------------------------------------------------------------- // Load Effect. This includes both the vertex and pixel shaders. // Also can include more than one technique. ShaderBytecode shaderByteCode = ShaderBytecode.CompileFromFile( "effectDx11.fx", "fx_5_0", ShaderFlags.EnableStrictness); var effect = new Effect(device11, shaderByteCode); // create triangle vertex data, making sure to rewind the stream afterward var verticesTriangle = new DataStream(VertexPositionColor.SizeInBytes * 3, true, true); verticesTriangle.Write(new VertexPositionColor(new Vector3(0.0f, 0.5f, 0.5f),new Color4(1.0f, 0.0f, 0.0f, 1.0f))); verticesTriangle.Write(new VertexPositionColor(new Vector3(0.5f, -0.5f, 0.5f),new Color4(0.0f, 1.0f, 0.0f, 1.0f))); verticesTriangle.Write(new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0.5f),new Color4(0.0f, 0.0f, 1.0f, 1.0f))); verticesTriangle.Position = 0; // create the triangle vertex layout and buffer var layoutColor = new InputLayout(device11, effect.GetTechniqueByName("Color").GetPassByIndex(0).Description.Signature, VertexPositionColor.inputElements); var vertexBufferColor = new Buffer(device11, verticesTriangle, (int)verticesTriangle.Length, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); verticesTriangle.Close(); // create overlay vertex data, making sure to rewind the stream afterward // Top Left of screen is -1, +1 // Bottom Right of screen is +1, -1 var verticesText = new DataStream(VertexPositionTexture.SizeInBytes * 4, true, true); verticesText.Write(new VertexPositionTexture(new Vector3(-1, 1, 0),new Vector2(0, 0f))); verticesText.Write(new VertexPositionTexture(new Vector3(1, 1, 0),new Vector2(1, 0))); verticesText.Write(new VertexPositionTexture(new Vector3(-1, -1, 0),new Vector2(0, 1))); verticesText.Write(new VertexPositionTexture(new Vector3(1, -1, 0),new Vector2(1, 1))); verticesText.Position = 0; // create the overlay vertex layout and buffer var layoutOverlay = new InputLayout(device11, effect.GetTechniqueByName("Overlay").GetPassByIndex(0).Description.Signature, VertexPositionTexture.inputElements); var vertexBufferOverlay = new Buffer(device11, verticesText, (int)verticesText.Length, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); verticesText.Close(); // Think of the shared textureD3D10 as an overlay. // The overlay needs to show the 2d content but let the underlying triangle (or whatever) // show thru, which is accomplished by blending. var bsd = new BlendStateDescription(); bsd.RenderTarget[0].IsBlendEnabled = true; bsd.RenderTarget[0].SourceBlend = BlendOption.SourceColor; bsd.RenderTarget[0].DestinationBlend = BlendOption.BlendFactor; bsd.RenderTarget[0].BlendOperation = BlendOperation.Add; bsd.RenderTarget[0].SourceAlphaBlend = BlendOption.One; bsd.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero; bsd.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; bsd.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; var blendStateTransparent = new BlendState(device11, bsd); // --------------------------------------------------------------------------------------------------- // Create and tesselate an ellipse // --------------------------------------------------------------------------------------------------- var center = new DrawingPointF(form.ClientSize.Width/2.0f, form.ClientSize.Height/2.0f); var ellipse = new EllipseGeometry(factory2D, new Ellipse(center, form.ClientSize.Width / 2.0f, form.ClientSize.Height / 2.0f)); // Populate a PathGeometry from Ellipse tessellation var tesselatedGeometry = new PathGeometry(factory2D); _geometrySink = tesselatedGeometry.Open(); // Force RoundLineJoin otherwise the tesselated looks buggy at line joins _geometrySink.SetSegmentFlags(PathSegment.ForceRoundLineJoin); // Tesselate the ellipse to our TessellationSink ellipse.Tessellate(1, this); _geometrySink.Close(); // --------------------------------------------------------------------------------------------------- // Acquire the mutexes. These are needed to assure the device in use has exclusive access to the surface // --------------------------------------------------------------------------------------------------- var device10Mutex = textureD3D10.QueryInterface<KeyedMutex>(); var device11Mutex = textureD3D11.QueryInterface<KeyedMutex>(); // --------------------------------------------------------------------------------------------------- // Main rendering loop // --------------------------------------------------------------------------------------------------- bool first = true; RenderLoop .Run(form, () => { if(first) { form.Activate(); first = false; } // clear the render target to black context.ClearRenderTargetView(renderTargetView, Colors.DarkSlateGray); // Draw the triangle context.InputAssembler.InputLayout = layoutColor; context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBufferColor, VertexPositionColor.SizeInBytes, 0)); context.OutputMerger.BlendState = null; var currentTechnique = effect.GetTechniqueByName("Color"); for (var pass = 0; pass < currentTechnique.Description.PassCount; ++pass) { using (var effectPass = currentTechnique.GetPassByIndex(pass)) { System.Diagnostics.Debug.Assert(effectPass.IsValid, "Invalid EffectPass"); effectPass.Apply(context); } context.Draw(3, 0); }; // Draw Ellipse on the shared Texture2D device10Mutex.Acquire(0, 100); renderTarget2D.BeginDraw(); renderTarget2D.Clear(Colors.Black); renderTarget2D.DrawGeometry(tesselatedGeometry, solidColorBrush); renderTarget2D.DrawEllipse(new Ellipse(center, 200, 200), solidColorBrush, 20, null); renderTarget2D.EndDraw(); device10Mutex.Release(0); // Draw the shared texture2D onto the screen, blending the 2d content in device11Mutex.Acquire(0, 100); var srv = new ShaderResourceView(device11, textureD3D11); effect.GetVariableByName("g_Overlay").AsShaderResource().SetResource(srv); context.InputAssembler.InputLayout = layoutOverlay; context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip; context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBufferOverlay, VertexPositionTexture.SizeInBytes, 0)); context.OutputMerger.BlendState = blendStateTransparent; currentTechnique = effect.GetTechniqueByName("Overlay"); for (var pass = 0; pass < currentTechnique.Description.PassCount; ++pass) { using (var effectPass = currentTechnique.GetPassByIndex(pass)) { System.Diagnostics.Debug.Assert(effectPass.IsValid, "Invalid EffectPass"); effectPass.Apply(context); } context.Draw(4, 0); } srv.Dispose(); device11Mutex.Release(0); swapChain.Present(0, PresentFlags.None); }); // dispose everything vertexBufferColor.Dispose(); vertexBufferOverlay.Dispose(); layoutColor.Dispose(); layoutOverlay.Dispose(); effect.Dispose(); shaderByteCode.Dispose(); renderTarget2D.Dispose(); swapChain.Dispose(); device11.Dispose(); device10.Dispose(); textureD3D10.Dispose(); textureD3D11.Dispose(); factory1.Dispose(); adapter1.Dispose(); sharedResource.Dispose(); factory2D.Dispose(); surface.Dispose(); solidColorBrush.Dispose(); blendStateTransparent.Dispose(); device10Mutex.Dispose(); device11Mutex.Dispose(); }
static void Main() { // input and output files are supposed to be in the program folder var inputPath = "Input.png"; var outputPath = "Output.png"; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // INITIALIZATION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // initialize the D3D device which will allow to render to image any graphics - 3D or 2D var defaultDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware, d3d.DeviceCreationFlags.VideoSupport | d3d.DeviceCreationFlags.BgraSupport | d3d.DeviceCreationFlags.Debug); // take out the Debug flag for better performance var d3dDevice = defaultDevice.QueryInterface <d3d.Device1>(); // get a reference to the Direct3D 11.1 device var dxgiDevice = d3dDevice.QueryInterface <dxgi.Device>(); // get a reference to DXGI device var d2dDevice = new d2.Device(dxgiDevice); // initialize the D2D device var imagingFactory = new wic.ImagingFactory2(); // initialize the WIC factory // initialize the DeviceContext - it will be the D2D render target and will allow all rendering operations var d2dContext = new d2.DeviceContext(d2dDevice, d2.DeviceContextOptions.None); var dwFactory = new dw.Factory(); // specify a pixel format that is supported by both D2D and WIC var d2PixelFormat = new d2.PixelFormat(dxgi.Format.R8G8B8A8_UNorm, d2.AlphaMode.Premultiplied); // if in D2D was specified an R-G-B-A format - use the same for wic var wicPixelFormat = wic.PixelFormat.Format32bppPRGBA; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // IMAGE LOADING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var decoder = new wic.PngBitmapDecoder(imagingFactory); // we will load a PNG image var inputStream = new wic.WICStream(imagingFactory, inputPath, NativeFileAccess.Read); // open the image file for reading decoder.Initialize(inputStream, wic.DecodeOptions.CacheOnLoad); // decode the loaded image to a format that can be consumed by D2D var formatConverter = new wic.FormatConverter(imagingFactory); formatConverter.Initialize(decoder.GetFrame(0), wicPixelFormat); // load the base image into a D2D Bitmap //var inputBitmap = d2.Bitmap1.FromWicBitmap(d2dContext, formatConverter, new d2.BitmapProperties1(d2PixelFormat)); // store the image size - output will be of the same size var inputImageSize = formatConverter.Size; var pixelWidth = inputImageSize.Width; var pixelHeight = inputImageSize.Height; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // EFFECT SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Effect 1 : BitmapSource - take decoded image data and get a BitmapSource from it var bitmapSourceEffect = new d2.Effects.BitmapSource(d2dContext); bitmapSourceEffect.WicBitmapSource = formatConverter; // Effect 2 : GaussianBlur - give the bitmapsource a gaussian blurred effect var gaussianBlurEffect = new d2.Effects.GaussianBlur(d2dContext); gaussianBlurEffect.SetInput(0, bitmapSourceEffect.Output, true); gaussianBlurEffect.StandardDeviation = 5f; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // OVERLAY TEXT SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var textFormat = new dw.TextFormat(dwFactory, "Arial", 15f); // create the text format of specified font configuration // draw a long text to show the automatic line wrapping var textToDraw = "Some long text to show the drawing of preformatted " + "glyphs using DirectWrite on the Direct2D surface." + " Notice the automatic wrapping of line if it exceeds desired width."; // create the text layout - this improves the drawing performance for static text // as the glyph positions are precalculated var textLayout = new dw.TextLayout(dwFactory, textToDraw, textFormat, 300f, 1000f); var textBrush = new d2.SolidColorBrush(d2dContext, Color.LightGreen); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // RENDER TARGET SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // create the d2d bitmap description using default flags (from SharpDX samples) and 96 DPI var d2dBitmapProps = new d2.BitmapProperties1(d2PixelFormat, 96, 96, d2.BitmapOptions.Target | d2.BitmapOptions.CannotDraw); // the render target var d2dRenderTarget = new d2.Bitmap1(d2dContext, new Size2(pixelWidth, pixelHeight), d2dBitmapProps); d2dContext.Target = d2dRenderTarget; // associate bitmap with the d2d context // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // DRAWING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // slow preparations - fast drawing: d2dContext.BeginDraw(); d2dContext.DrawImage(gaussianBlurEffect); d2dContext.DrawTextLayout(new Vector2(5f, 5f), textLayout, textBrush); d2dContext.EndDraw(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // IMAGE SAVING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // delete the output file if it already exists if (System.IO.File.Exists(outputPath)) { System.IO.File.Delete(outputPath); } // use the appropiate overload to write either to stream or to a file var stream = new wic.WICStream(imagingFactory, outputPath, NativeFileAccess.Write); // select the image encoding format HERE var encoder = new wic.PngBitmapEncoder(imagingFactory); encoder.Initialize(stream); var bitmapFrameEncode = new wic.BitmapFrameEncode(encoder); bitmapFrameEncode.Initialize(); bitmapFrameEncode.SetSize(pixelWidth, pixelHeight); bitmapFrameEncode.SetPixelFormat(ref wicPixelFormat); // this is the trick to write D2D1 bitmap to WIC var imageEncoder = new wic.ImageEncoder(imagingFactory, d2dDevice); imageEncoder.WriteFrame(d2dRenderTarget, bitmapFrameEncode, new wic.ImageParameters(d2PixelFormat, 96, 96, 0, 0, pixelWidth, pixelHeight)); bitmapFrameEncode.Commit(); encoder.Commit(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CLEANUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // dispose everything and free used resources bitmapFrameEncode.Dispose(); encoder.Dispose(); stream.Dispose(); textBrush.Dispose(); textLayout.Dispose(); textFormat.Dispose(); formatConverter.Dispose(); gaussianBlurEffect.Dispose(); bitmapSourceEffect.Dispose(); d2dRenderTarget.Dispose(); inputStream.Dispose(); decoder.Dispose(); d2dContext.Dispose(); dwFactory.Dispose(); imagingFactory.Dispose(); d2dDevice.Dispose(); dxgiDevice.Dispose(); d3dDevice.Dispose(); defaultDevice.Dispose(); // show the result System.Diagnostics.Process.Start(outputPath); }
static void Main() { // input and output files are supposed to be in the program folder var inputPath = "Input.png"; var outputPath = "Output.png"; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // INITIALIZATION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // initialize the D3D device which will allow to render to image any graphics - 3D or 2D var defaultDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware, d3d.DeviceCreationFlags.VideoSupport | d3d.DeviceCreationFlags.BgraSupport | d3d.DeviceCreationFlags.Debug); // take out the Debug flag for better performance var d3dDevice = defaultDevice.QueryInterface<d3d.Device1>(); // get a reference to the Direct3D 11.1 device var dxgiDevice = d3dDevice.QueryInterface<dxgi.Device>(); // get a reference to DXGI device var d2dDevice = new d2.Device(dxgiDevice); // initialize the D2D device var imagingFactory = new wic.ImagingFactory2(); // initialize the WIC factory // initialize the DeviceContext - it will be the D2D render target and will allow all rendering operations var d2dContext = new d2.DeviceContext(d2dDevice, d2.DeviceContextOptions.None); var dwFactory = new dw.Factory(); // specify a pixel format that is supported by both D2D and WIC var d2PixelFormat = new d2.PixelFormat(dxgi.Format.R8G8B8A8_UNorm, d2.AlphaMode.Premultiplied); // if in D2D was specified an R-G-B-A format - use the same for wic var wicPixelFormat = wic.PixelFormat.Format32bppPRGBA; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // IMAGE LOADING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var decoder = new wic.PngBitmapDecoder(imagingFactory); // we will load a PNG image var inputStream = new wic.WICStream(imagingFactory, inputPath, NativeFileAccess.Read); // open the image file for reading decoder.Initialize(inputStream, wic.DecodeOptions.CacheOnLoad); // decode the loaded image to a format that can be consumed by D2D var formatConverter = new wic.FormatConverter(imagingFactory); formatConverter.Initialize(decoder.GetFrame(0), wicPixelFormat); // load the base image into a D2D Bitmap //var inputBitmap = d2.Bitmap1.FromWicBitmap(d2dContext, formatConverter, new d2.BitmapProperties1(d2PixelFormat)); // store the image size - output will be of the same size var inputImageSize = formatConverter.Size; var pixelWidth = inputImageSize.Width; var pixelHeight = inputImageSize.Height; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // EFFECT SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Effect 1 : BitmapSource - take decoded image data and get a BitmapSource from it var bitmapSourceEffect = new d2.Effects.BitmapSource(d2dContext); bitmapSourceEffect.WicBitmapSource = formatConverter; // Effect 2 : GaussianBlur - give the bitmapsource a gaussian blurred effect var gaussianBlurEffect = new d2.Effects.GaussianBlur(d2dContext); gaussianBlurEffect.SetInput(0, bitmapSourceEffect.Output, true); gaussianBlurEffect.StandardDeviation = 5f; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // OVERLAY TEXT SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var textFormat = new dw.TextFormat(dwFactory, "Arial", 15f); // create the text format of specified font configuration // draw a long text to show the automatic line wrapping var textToDraw = "Some long text to show the drawing of preformatted " + "glyphs using DirectWrite on the Direct2D surface." + " Notice the automatic wrapping of line if it exceeds desired width."; // create the text layout - this improves the drawing performance for static text // as the glyph positions are precalculated var textLayout = new dw.TextLayout(dwFactory, textToDraw, textFormat, 300f, 1000f); var textBrush = new d2.SolidColorBrush(d2dContext, Color.LightGreen); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // RENDER TARGET SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // create the d2d bitmap description using default flags (from SharpDX samples) and 96 DPI var d2dBitmapProps = new d2.BitmapProperties1(d2PixelFormat, 96, 96, d2.BitmapOptions.Target | d2.BitmapOptions.CannotDraw); // the render target var d2dRenderTarget = new d2.Bitmap1(d2dContext, new Size2(pixelWidth, pixelHeight), d2dBitmapProps); d2dContext.Target = d2dRenderTarget; // associate bitmap with the d2d context // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // DRAWING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // slow preparations - fast drawing: d2dContext.BeginDraw(); d2dContext.DrawImage(gaussianBlurEffect); d2dContext.DrawTextLayout(new Vector2(5f, 5f), textLayout, textBrush); d2dContext.EndDraw(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // IMAGE SAVING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // delete the output file if it already exists if (System.IO.File.Exists(outputPath)) System.IO.File.Delete(outputPath); // use the appropiate overload to write either to stream or to a file var stream = new wic.WICStream(imagingFactory, outputPath, NativeFileAccess.Write); // select the image encoding format HERE var encoder = new wic.PngBitmapEncoder(imagingFactory); encoder.Initialize(stream); var bitmapFrameEncode = new wic.BitmapFrameEncode(encoder); bitmapFrameEncode.Initialize(); bitmapFrameEncode.SetSize(pixelWidth, pixelHeight); bitmapFrameEncode.SetPixelFormat(ref wicPixelFormat); // this is the trick to write D2D1 bitmap to WIC var imageEncoder = new wic.ImageEncoder(imagingFactory, d2dDevice); imageEncoder.WriteFrame(d2dRenderTarget, bitmapFrameEncode, new wic.ImageParameters(d2PixelFormat, 96, 96, 0, 0, pixelWidth, pixelHeight)); bitmapFrameEncode.Commit(); encoder.Commit(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CLEANUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // dispose everything and free used resources bitmapFrameEncode.Dispose(); encoder.Dispose(); stream.Dispose(); textBrush.Dispose(); textLayout.Dispose(); textFormat.Dispose(); formatConverter.Dispose(); gaussianBlurEffect.Dispose(); bitmapSourceEffect.Dispose(); d2dRenderTarget.Dispose(); inputStream.Dispose(); decoder.Dispose(); d2dContext.Dispose(); dwFactory.Dispose(); imagingFactory.Dispose(); d2dDevice.Dispose(); dxgiDevice.Dispose(); d3dDevice.Dispose(); defaultDevice.Dispose(); // show the result System.Diagnostics.Process.Start(outputPath); }