使用 DirectX 或 OpenGL 会加速 windows 表单上的 2D 渲染吗?
Will using DirectX or OpenGL speed up 2D Rendering on a windows form?
我正在做一个结构光项目,我需要以 60fps 的速度投射本质上是条形码的东西。这些代码是根据 1920x1200 的位图图像构建的。在 C# 中使用 GDI 时,我在一台非常糟糕的计算机上只能获得大约 19fps。我现在正在研究 SharpDX,在投入大量时间之前,我想知道通过 DirectX 或 OpenGL 将图像渲染到屏幕上是否真的会更快?
示例代码:
// Gets a reference to the current BufferedGraphicsContext
currentContext = BufferedGraphicsManager.Current;
List<Image> imagesGrayCode = new List<Image>();
Bitmap bitmap = (Bitmap)Image.FromFile("F:/LAB/Hardware Triggering Demo/Lib/Patterns_11bit_RLL.tiff");
int count = bitmap.GetFrameCount(FrameDimension.Page);
for (int idx = 0; idx < count; idx++)
{
// save each frame to a bytestream
bitmap.SelectActiveFrame(FrameDimension.Page, idx);
MemoryStream byteStream = new MemoryStream();
bitmap.Save(byteStream, ImageFormat.Tiff);
// and then create a new Image from it
imagesGrayCode.Add(Image.FromStream(byteStream));
//this.progressBar1.Value = idx;
}
Thread.Sleep(1000);
stopwatch = Stopwatch.StartNew();
int acq_wait_time = 10;
for (int i = 0; i < 10; i++)
{
foreach (Image img in imagesGrayCode)
{
myBuffer.Graphics.DrawImage(img, this.DisplayRectangle);
// Renders the contents of the buffer to the drawing surface associated with the buffer.
myBuffer.Render();
// Renders the contents of the buffer to the specified drawing surface.
myBuffer.Render(this.CreateGraphics());
//System.Threading.Thread.Sleep(acq_wait_time);
stopwatch.Reset();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < acq_wait_time)
{ }
FPS++;
Application.DoEvents();
}
}
更新代码:
// Gets a reference to the current BufferedGraphicsContext
currentContext = BufferedGraphicsManager.Current;
List<Image> imagesGrayCode = new List<Image>();
List<BufferedGraphics> ImageBuffers = new List<BufferedGraphics>();
Bitmap bitmap = (Bitmap)Image.FromFile("F:/LAB/Hardware Triggering Demo/Lib/Patterns_11bit_RLL.tiff");
int count = bitmap.GetFrameCount(FrameDimension.Page);
for (int idx = 0; idx < count; idx++)
{
// save each frame to a bytestream
bitmap.SelectActiveFrame(FrameDimension.Page, idx);
MemoryStream byteStream = new MemoryStream();
bitmap.Save(byteStream, ImageFormat.Tiff);
// and then create a new Image from it
imagesGrayCode.Add(Image.FromStream(byteStream));
//this.progressBar1.Value = idx;
}
//create a buffer from each image in memory
for (int i = 0; i < imagesGrayCode.Count(); i++)
{
ImageBuffers.Add(currentContext.Allocate(this.CreateGraphics(),this.DisplayRectangle));
ImageBuffers.ElementAt(i).Graphics.DrawImage(imagesGrayCode.ElementAt(i), this.DisplayRectangle);
ImageBuffers.ElementAt(i).Render();
}
Thread.Sleep(1000);
stopwatch = Stopwatch.StartNew();
int acq_wait_time = 10;
for (int x = 0; x < 10; x++)
{
//display image buffers sequentially
for (int i = 0; i < imagesGrayCode.Count(); i++)
{
// Renders the contents of the buffer to the specified drawing surface.
ImageBuffers.ElementAt(i).Render(this.CreateGraphics());
//System.Threading.Thread.Sleep(acq_wait_time);
stopwatch.Reset();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < acq_wait_time)
{ }
FPS++;
Application.DoEvents();
}
}
您正在绘图 > 渲染 > 绘图 > 渲染 > 绘图 > 渲染等。您可以提前完成所有绘图,因此您只需要在每一帧上渲染。使用更多的 myBuffer 是什么;每张图片一个。
Profiler 工具非常适合解决这些问题。我是根据你的部分代码和我的经验猜测的,但是分析器可以准确地告诉你每个函数完成需要多长时间。
我正在做一个结构光项目,我需要以 60fps 的速度投射本质上是条形码的东西。这些代码是根据 1920x1200 的位图图像构建的。在 C# 中使用 GDI 时,我在一台非常糟糕的计算机上只能获得大约 19fps。我现在正在研究 SharpDX,在投入大量时间之前,我想知道通过 DirectX 或 OpenGL 将图像渲染到屏幕上是否真的会更快?
示例代码:
// Gets a reference to the current BufferedGraphicsContext
currentContext = BufferedGraphicsManager.Current;
List<Image> imagesGrayCode = new List<Image>();
Bitmap bitmap = (Bitmap)Image.FromFile("F:/LAB/Hardware Triggering Demo/Lib/Patterns_11bit_RLL.tiff");
int count = bitmap.GetFrameCount(FrameDimension.Page);
for (int idx = 0; idx < count; idx++)
{
// save each frame to a bytestream
bitmap.SelectActiveFrame(FrameDimension.Page, idx);
MemoryStream byteStream = new MemoryStream();
bitmap.Save(byteStream, ImageFormat.Tiff);
// and then create a new Image from it
imagesGrayCode.Add(Image.FromStream(byteStream));
//this.progressBar1.Value = idx;
}
Thread.Sleep(1000);
stopwatch = Stopwatch.StartNew();
int acq_wait_time = 10;
for (int i = 0; i < 10; i++)
{
foreach (Image img in imagesGrayCode)
{
myBuffer.Graphics.DrawImage(img, this.DisplayRectangle);
// Renders the contents of the buffer to the drawing surface associated with the buffer.
myBuffer.Render();
// Renders the contents of the buffer to the specified drawing surface.
myBuffer.Render(this.CreateGraphics());
//System.Threading.Thread.Sleep(acq_wait_time);
stopwatch.Reset();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < acq_wait_time)
{ }
FPS++;
Application.DoEvents();
}
}
更新代码:
// Gets a reference to the current BufferedGraphicsContext
currentContext = BufferedGraphicsManager.Current;
List<Image> imagesGrayCode = new List<Image>();
List<BufferedGraphics> ImageBuffers = new List<BufferedGraphics>();
Bitmap bitmap = (Bitmap)Image.FromFile("F:/LAB/Hardware Triggering Demo/Lib/Patterns_11bit_RLL.tiff");
int count = bitmap.GetFrameCount(FrameDimension.Page);
for (int idx = 0; idx < count; idx++)
{
// save each frame to a bytestream
bitmap.SelectActiveFrame(FrameDimension.Page, idx);
MemoryStream byteStream = new MemoryStream();
bitmap.Save(byteStream, ImageFormat.Tiff);
// and then create a new Image from it
imagesGrayCode.Add(Image.FromStream(byteStream));
//this.progressBar1.Value = idx;
}
//create a buffer from each image in memory
for (int i = 0; i < imagesGrayCode.Count(); i++)
{
ImageBuffers.Add(currentContext.Allocate(this.CreateGraphics(),this.DisplayRectangle));
ImageBuffers.ElementAt(i).Graphics.DrawImage(imagesGrayCode.ElementAt(i), this.DisplayRectangle);
ImageBuffers.ElementAt(i).Render();
}
Thread.Sleep(1000);
stopwatch = Stopwatch.StartNew();
int acq_wait_time = 10;
for (int x = 0; x < 10; x++)
{
//display image buffers sequentially
for (int i = 0; i < imagesGrayCode.Count(); i++)
{
// Renders the contents of the buffer to the specified drawing surface.
ImageBuffers.ElementAt(i).Render(this.CreateGraphics());
//System.Threading.Thread.Sleep(acq_wait_time);
stopwatch.Reset();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < acq_wait_time)
{ }
FPS++;
Application.DoEvents();
}
}
您正在绘图 > 渲染 > 绘图 > 渲染 > 绘图 > 渲染等。您可以提前完成所有绘图,因此您只需要在每一帧上渲染。使用更多的 myBuffer 是什么;每张图片一个。
Profiler 工具非常适合解决这些问题。我是根据你的部分代码和我的经验猜测的,但是分析器可以准确地告诉你每个函数完成需要多长时间。