为什么用managed directX绘2D图的速度比GDI+还慢?

tommake 2010-02-25 11:13:16
这是一段移动图片的代码
图片是64*64的。
private void panel1_Paint(object sender, PaintEventArgs e)
{
string file = @"D:\d.JPG";
int a = 0;
if (a == 0)
{
for (int i = 0; i < 500; i++)
{
Draw.DrawImage(file, panel1,i,0);//自己用dx封装的一个简单的类
Application.DoEvents();
}
}
else
{
for (int i = 0; i < 500; i++)
{

e.Graphics.DrawImage(Image.FromFile(file), i, 0);
Application.DoEvents();
}
}
前者是DX绘图。后者是GDI+。
但是在移动速度上后者比前者快好几倍~~
是不是我的代码有什么地方不对?

这是draw.drawImage的代码:
public static void DrawImage(String File, Control control,int x,int y)
{
pp.Windowed = true;
pp.SwapEffect = SwapEffect.Discard;
de = new Device(0, DeviceType.Hardware, control, CreateFlags.HardwareVertexProcessing, pp);
sp = new Sprite(de);
te = TextureLoader.FromFile(de, File);
de.BeginScene();
de.Clear(ClearFlags.Target, Color.White, 1.0f, 0);
sp.Begin(SpriteFlags.AlphaBlend);
sp.Draw(te, Vector3.Empty, new Vector3(x, y, 0), Color.White.ToArgb());
sp.End();
de.EndScene();
de.Present();
te.Dispose();
de.Dispose();
sp.Dispose();
}
...全文
533 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
pakacy 2010-10-17
  • 打赏
  • 举报
回复
来学习了
lindenrty 2010-10-08
  • 打赏
  • 举报
回复
其实本身就有问题 DX控制动画效果都是以刷新来控制的
而不是自己写循环
tommake 2010-02-27
  • 打赏
  • 举报
回复
问题已经解决...
原来是窗口模式下的垂直同步问题...
presentParams.PresentationInterval = PresentInterval.Immediate
即可....
引力场变动源 2010-02-25
  • 打赏
  • 举报
回复
怎么说呢……D3D在你的这种场合的确性能不高,因为CPU和GPU的同步需要消耗很多时间。D3D更适合一次绘制500个甚至500万个图片,而不是分500次每次绘制1个图片的场合。
tommake 2010-02-25
  • 打赏
  • 举报
回复
引用 6 楼 xingzhe2001 的回复:
正确的顺序是这样

beginScene
clear

for (int i = 0; i < 500; i++)
                {
                    Draw.DrawImage(file, panel1,i,0);//自己用dx封装的一个简单的类
                    Application.DoEvents();
                }
endScene

这样的话不是没有动画效果了吗?
xingzhe2001 2010-02-25
  • 打赏
  • 举报
回复
正确的顺序是这样

beginScene
clear

for (int i = 0; i < 500; i++)
{
Draw.DrawImage(file, panel1,i,0);//自己用dx封装的一个简单的类
Application.DoEvents();
}
endScene
xingzhe2001 2010-02-25
  • 打赏
  • 举报
回复
引用 2 楼 tommake 的回复:
引用 1 楼 xingzhe2001 的回复:每次绘制你都会new 一个Device,当然会慢,你可以在一个初始化的地方new Device一次,以后就重用这个device
按照楼上的方法,我修改了下,速度确实有所提高,但是还是不如GDI+··
我把sprite和texture都修改了.

把clear也去掉
引力场变动源 2010-02-25
  • 打赏
  • 举报
回复
原来是要平铺500次,抱歉,看错了,呵呵
引力场变动源 2010-02-25
  • 打赏
  • 举报
回复
绘制的方法不对,panel1_Paint里面只要绘制一次就可以了,不用循环那么多次。
tommake 2010-02-25
  • 打赏
  • 举报
回复
引用 1 楼 xingzhe2001 的回复:
每次绘制你都会new 一个Device,当然会慢,你可以在一个初始化的地方new Device一次,以后就重用这个device

按照楼上的方法,我修改了下,速度确实有所提高,但是还是不如GDI+··
我把sprite和texture都修改了.
xingzhe2001 2010-02-25
  • 打赏
  • 举报
回复
每次绘制你都会new 一个Device,当然会慢,你可以在一个初始化的地方new Device一次,以后就重用这个device
tommake 2010-02-25
  • 打赏
  • 举报
回复
引用 12 楼 silenker 的回复:
引用 11 楼 tommake 的回复:引用 10 楼 silenker 的回复:引用现代PC的体系结构决定了我们在提交三角形时需要通过d3d runtime和driver。我们每一次提交三角形都要通过调用d3d runtime给我们的接口,而d3d runtime又会通知driver去对相关硬件做操作。如果你的场景中有10,000个三角形,但你每次只提交10多个,那么这样下来就会需要提交1,000次左右,也就是说调用1,000次左右的DP/DIP。这样d3d runtime和?- 这么说,MS推荐的D3D下的2D绘图模式(就是texture+Sprite)本身就是有问题的啦?是不是还得用DirectDraw?

本身没问题,sprite在begin和end之间是可以绘制成千上万个2D图像的,然后end的时候一次画出来。
只是D3D并不适合直接做程序界面,需要更深层次的封装,比如Windows7下面的Direct2D,就是微软为了用D3D绘制界面新开发的产品。
而.net平台,则可以使用WPF来实现,在硬件加速可用的情况下,WPF是使用D3D加速的。

受教了....
引力场变动源 2010-02-25
  • 打赏
  • 举报
回复
引用 11 楼 tommake 的回复:
引用 10 楼 silenker 的回复:引用现代PC的体系结构决定了我们在提交三角形时需要通过d3d runtime和driver。我们每一次提交三角形都要通过调用d3d runtime给我们的接口,而d3d runtime又会通知driver去对相关硬件做操作。如果你的场景中有10,000个三角形,但你每次只提交10多个,那么这样下来就会需要提交1,000次左右,也就是说调用1,000次左右的DP/DIP。这样d3d runtime和?-
这么说,MS推荐的D3D下的2D绘图模式(就是texture+Sprite)本身就是有问题的啦?
是不是还得用DirectDraw?


本身没问题,sprite在begin和end之间是可以绘制成千上万个2D图像的,然后end的时候一次画出来。
只是D3D并不适合直接做程序界面,需要更深层次的封装,比如Windows7下面的Direct2D,就是微软为了用D3D绘制界面新开发的产品。
而.net平台,则可以使用WPF来实现,在硬件加速可用的情况下,WPF是使用D3D加速的。
tommake 2010-02-25
  • 打赏
  • 举报
回复
引用 10 楼 silenker 的回复:
引用现代PC的体系结构决定了我们在提交三角形时需要通过d3d runtime和driver。我们每一次提交三角形都要通过调用d3d runtime给我们的接口,而d3d runtime又会通知driver去对相关硬件做操作。如果你的场景中有10,000个三角形,但你每次只提交10多个,那么这样下来就会需要提交1,000次左右,也就是说调用1,000次左右的DP/DIP。这样d3d runtime和?-

这么说,MS推荐的D3D下的2D绘图模式(就是texture+Sprite)本身就是有问题的啦?
是不是还得用DirectDraw?
引力场变动源 2010-02-25
  • 打赏
  • 举报
回复
引用
现代PC的体系结构决定了我们在提交三角形时需要通过d3d runtime和driver。我们每一次提交三角形都要通过调用d3d runtime给我们的接口,而d3d runtime又会通知driver去对相关硬件做操作。如果你的场景中有10,000个三角形,但你每次只提交10多个,那么这样下来就会需要提交1,000次左右,也就是说调用1,000次左右的DP/DIP。这样d3d runtime和driver就忙于和硬件(主要应是AGP总线和GPU)打交道,而高度优化的显卡流水线只是每次处理了10多个三角形就被迫全线停止,然后等待下一次启动流水线。

这样大部分时间都被CPU花在了愚蠢的“多次提交三角形”上,而GPU闲在那边没事做。GPU没事做意味着什么?意味着我们可以大幅增加三角形复杂度!反正GPU闲着也是闲着,每次处理10个三角形停下和每次处理100个三角形停下,差不了多少时间。还意味着我们可以用更多的Vertex Shader/Pixel Shader,反正是闲着嘛!
xychzh 2010-02-25
  • 打赏
  • 举报
回复
引用 8 楼 silenker 的回复:
怎么说呢……D3D在你的这种场合的确性能不高,因为CPU和GPU的同步需要消耗很多时间。D3D更适合一次绘制500个甚至500万个图片,而不是分500次每次绘制1个图片的场合。

学习了。

8,305

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧