2015-09-12 6 views
0

Я хотел бы реализовать аппаратное ускорение для приложения C# WinForms. Причина в том, что мне приходится рисовать изображения размером 150 x 720p, а 5 элементов управления изображением занимают слишком много времени (масштабирование + рисование изображений), и поэтому возникают проблемы с утилизацией и перезагрузкой. Итак, я имел дело с ShapeDX.C# WinForm - SharpDX.Toolkit.Graphics draw 2D Texture

Но теперь я застрял и не знаю, как нарисовать 2D-текстуру. Чтобы проверить код, у меня есть только тестовая кнопка и один PictureBox.

Когда я запускаю код в PictureBox, также загружается DirectX (Draw или 3D). Я признаю черный фон. Но я не понимаю, как нужно нарисовать текстуру.

 String imageFile = "Image.JPG"; 

     Control TargetControl = this.pictureBoxCurrentFrameL; 
     int TotalWidth = TargetControl.Width; 
     int TotalHeight = TargetControl.Height; 

     SharpDX.Direct3D11.Device defaultDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware, SharpDX.Direct3D11.DeviceCreationFlags.Debug); 

     SharpDX.Toolkit.Graphics.GraphicsDevice graphicsDevice = SharpDX.Toolkit.Graphics.GraphicsDevice.New(defaultDevice); 
     SharpDX.Toolkit.Graphics.PresentationParameters presentationParameters = new SharpDX.Toolkit.Graphics.PresentationParameters(); 
     presentationParameters.DeviceWindowHandle = this.pictureBoxCurrentFrameL.Handle; 
     presentationParameters.BackBufferWidth = TotalWidth; 
     presentationParameters.BackBufferHeight = TotalHeight; 

     SharpDX.Toolkit.Graphics.SwapChainGraphicsPresenter swapChainGraphicsPresenter = new SharpDX.Toolkit.Graphics.SwapChainGraphicsPresenter(graphicsDevice, presentationParameters); 
     SharpDX.Toolkit.Graphics.Texture2D texture2D = SharpDX.Toolkit.Graphics.Texture2D.Load(graphicsDevice, imageFile); 

     //Now i should draw. But how? 

     swapChainGraphicsPresenter.Present();/**/ 

с помощью Microsoft Visual Studio 2015 Сообщество (.NET 4, C# WinForm) на Windows 10 SharpDX-SDK-2.6.3!

Благодарим за помощь.

+0

Как часто вам нужно обновить свой интерфейс? Сколько раз в секунду? Вы можете просто использовать GDI. – Lorek

+0

Я получаю до 150x 720p кадров в секунду. - 5x разных источников (30 кадров в секунду). 2x видео 720p (30 кадров в секунду) 2x 720p видеокадры (с признанным) 1x 720p видео кадров с конечным результатом распознавание шаблона разделен на несколько потоков. Окончательный расчет также выполняется в отдельном потоке. Все изображения генерируются другими потоками и являются асинхронными. –

+0

Я протестировал GDI сегодня. по-видимому, производительность похожа на контроль. Я думаю, что использование GDI лучше, чем управление. так что вы можете управлять рисунком (например, кадрировать кадры, распоряжаться и т. д.), но я бы предпочел использовать Direct Draw. Может ли кто-нибудь помочь мне с проблемой прямого рисования? –

ответ

2

Я решил проблему, просто переключившись на SlimDX (SlimDX Runtime .NET 4.0 x64 January 2012.msi, .Net4, Win10, MS Visual Studio Community 2015, Winforms App.). Существует несколько полезных уроков.

, чтобы использовать SlimDX, просто свяжите единственную DLL с проектом ура! после установки SlimDX u найдет этот файл SlimDX.dll где-нибудь на ур C Drive.

Важно понимать, что для Direct2D требуется по крайней мере один завод и цель рендеринга. RenderTarget указывает на объект, который будет использоваться (Control/form/etc), и берет на себя чертеж.

своп-цепочка не требуется. вероятно, используется внутренней целью рендеринга. самая большая часть состоит в том, чтобы преобразовать растровое изображение в полезный Bitmap Direct2D (для рисования). В противном случае вы можете обрабатывать данные растрового изображения также из MemoryStream.

Для тех, кто ищет решение тоже:

 Control targetControl = this.pictureBoxCurrentFrameL; 
     String imageFile = "Image.JPG"; 

     //Update control styles, works for forms, not for controls. I solve this later otherwise . 
     //this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
     //this.SetStyle(ControlStyles.Opaque, true); 
     //this.SetStyle(ControlStyles.ResizeRedraw, true); 

     //Get requested debug level 
     SlimDX.Direct2D.DebugLevel debugLevel = SlimDX.Direct2D.DebugLevel.None; 

     //Resources for Direct2D rendering 
     SlimDX.Direct2D.Factory d2dFactory = new SlimDX.Direct2D.Factory(SlimDX.Direct2D.FactoryType.Multithreaded, debugLevel); 

     //Create the render target 
     SlimDX.Direct2D.WindowRenderTarget d2dWindowRenderTarget = new SlimDX.Direct2D.WindowRenderTarget(d2dFactory, new SlimDX.Direct2D.WindowRenderTargetProperties() { 
      Handle = targetControl.Handle, 
      PixelSize = targetControl.Size, 
      PresentOptions = SlimDX.Direct2D.PresentOptions.Immediately 
     }); 

     //Paint! 
     d2dWindowRenderTarget.BeginDraw(); 
     d2dWindowRenderTarget.Clear(new SlimDX.Color4(Color.LightSteelBlue)); 

     //Convert System.Drawing.Bitmap into SlimDX.Direct2D.Bitmap! 
     System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)Properties.Resources.Image_720p;//loaded from embedded resource, can be changed to Bitmap.FromFile(imageFile); to load from hdd! 
     SlimDX.Direct2D.Bitmap d2dBitmap = null; 
     System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(new Point(0, 0), bitmap.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);//TODO: PixelFormat is very important!!! Check! 
     SlimDX.DataStream dataStream = new SlimDX.DataStream(bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, true, false); 
     SlimDX.Direct2D.PixelFormat d2dPixelFormat = new SlimDX.Direct2D.PixelFormat(SlimDX.DXGI.Format.B8G8R8A8_UNorm, SlimDX.Direct2D.AlphaMode.Premultiplied); 
     SlimDX.Direct2D.BitmapProperties d2dBitmapProperties = new SlimDX.Direct2D.BitmapProperties(); 
     d2dBitmapProperties.PixelFormat = d2dPixelFormat; 
     d2dBitmap = new SlimDX.Direct2D.Bitmap(d2dWindowRenderTarget, new Size(bitmap.Width, bitmap.Height), dataStream, bitmapData.Stride, d2dBitmapProperties); 
     bitmap.UnlockBits(bitmapData); 

     //Draw SlimDX.Direct2D.Bitmap 
     d2dWindowRenderTarget.DrawBitmap(d2dBitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));/**/ 

     d2dWindowRenderTarget.EndDraw(); 

     //Dispose everything u dont need anymore. 
     //bitmap.Dispose();//...... 

Так это супер проста в использовании Direct2D, весь код может быть сжат до 2-х основных линий + чертежа:

 SlimDX.Direct2D.Factory d2dFactory = new SlimDX.Direct2D.Factory(SlimDX.Direct2D.FactoryType.Multithreaded, SlimDX.Direct2D.DebugLevel.None); 
     SlimDX.Direct2D.WindowRenderTarget d2dWindowRenderTarget = new SlimDX.Direct2D.WindowRenderTarget(d2dFactory, new SlimDX.Direct2D.WindowRenderTargetProperties() { Handle = targetControl.Handle, PixelSize = targetControl.Size, PresentOptions = SlimDX.Direct2D.PresentOptions.Immediately }); 

     d2dWindowRenderTarget.BeginDraw(); 
     d2dWindowRenderTarget.Clear(new SlimDX.Color4(Color.LightSteelBlue)); 
     d2dWindowRenderTarget.DrawRectangle(new SlimDX.Direct2D.SolidColorBrush(d2dWindowRenderTarget, new SlimDX.Color4(Color.Red)), new Rectangle(20,20, targetControl.Width-40, targetControl.Height-40)); 
     d2dWindowRenderTarget.EndDraw();