性能调整动画 [英] Performance tuning animations

查看:61
本文介绍了性能调整动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!

我最近创建了一个控件,该控件可以放大和缩小图像并在图像上滚动(类似于在Google Earth上),但是当它开始设置动画时,我无法获得平滑的渲染.

顺便说一下,我使用了for循环来更改参数,然后刷新或使图像无效,并将double缓冲区设置为true.
我的for循环语句已经过调整,但是如果我想获得更平滑的渲染该怎么办?

我走错了方向吗?

也许我应该使用一些非托管代码?

在此先感谢您!

Hi all!

I recently created a control that will zoom in and out of an image and will scroll on it (something like on google earth), but I cannot get a smooth rendering when it begins to animate.

By the way I used a for-loop for changing parameters and then refresh or invalidate a piece of the image and set the double buffer to true.
My for-loop statement is tuned but what should I do if I want to get a smoother rendering?

Am I going in the wrong direction?

Maybe I should use some unmanaged code?

Thanks in advance!

推荐答案

目前尚不清楚您是如何实现的.例如,您的循环是否具有某种帧限制器?循环每秒最多执行30次(帧)吗?还是您像疯了似的ho着处理器?建议不要直接使用刷新,而应仅使无效.如果那意味着没有显示屏幕更新,则意味着您阻止了正常的程序更新屏幕.

另一个重要的事情是在另一个循环中进行处理.这在使用多处理器环境时甚至无济于事,而是在处理期间保持消息循环活动.当用户请求缩放时,您可以立即设置一些标志,指示可以中止处理.通过跳过不必要的处理,程序对用户的响应会更加迅速,并立即处理请求.不要忘记在线程内屈服(或sleep(0))并检查指标标志.还限制线程每秒处理30帧以上,并使用sleep方法释放处理器时间:
It is not exactly clear how you implemented it. Does your loop have some sort of frame limiter for example? Is the loop executed with a maximum of 30 times (frames) a second or are you hogging the processor like crazy? Using a refresh directly is not advisable and should stick with invalidate only. If that means that no screen updates are shown, it means that you prevent the normal program flow of updating your screen.

Another important thing is to do the processing in another loop. This not even helps when using a multi processor environment but keeps the message loop active during processing. When a user is requesting to zoom, you can then immediately set some flag indicating that the processing can be aborted. By skipping that unnecessary processing the program becomes more responsive to the user and processes request immediately. Don''t forget to yield (or sleep(0)) within the thread and check the indicator flag. Also limit the thread from processing more than 30 frames per second and use the sleep method to release processor time:
Sleep(Max((1000 / 30) - ({time in milliseconds when done} - {time in milliseconds when started}), 0));



Max方法用于确保不使用负数.还很容易检测到该值是否始终为负,并通过降低每秒的帧数来对此做出反应.

祝你好运!



GDI
http://www.aspfree .com/c/a/Code-Examples/Handling-Animation-and-Bitmaps-Using-GDI-for-Image-Manipulation/ [ C#中的2D"Nim"游戏开发和动画(第2部分) [ 2D动画图表 [在DirectDraw包装器上为C#旋转Sprite对象 [ DirectDraw和表面划线的介绍 [



The Max method is used to ensure that no negative numbers are used. It is also easy to detect if the value is negative all the time and react to that by lowering the frames per second.

Good luck!



GDI
http://www.aspfree.com/c/a/Code-Examples/Handling-Animation-and-Bitmaps-Using-GDI-for-Image-Manipulation/[^]

2D "Nim" Game Development and Animation in C# (Part 2)[^]

2D Animated Charts[^]

DirectDraw:
Rotating Sprite Objects on DirectDraw Wrapper for C#[^]

Introduction to DirectDraw and Surface Blitting[^]


EF Nijboer忙于某些事情-for循环类型可能不是一个好主意,就像那个人说的那样:不要刷新.

您可以尝试以下操作:
使用计时器来使图像占用的屏幕区域无效,并且仅在
OnPaint方法 [^ ]

这将使您的应用程序对其他用户操作做出响应,并且基本上是旧的" Windows api设计成工作方式的方式.如果系统由于某种原因无法跟上动画帧速率",则多个无效项将合并到一个WM_PAINT中.

如果您在此阶段还没有做很多工作,请考虑将您的解决方案移到WPF,在WPF中这样的东西可以在框架中找到现成的实现.

如果您将PictureBox用于图像,则可以使用本文概述的方法来解决问题:
http://www.java2s.com/Tutorial/VB/0300__2D-Graphics/Programthatanimatesaseriesofimages.htm [ ^ ]

它本质上是使用我上面概述的方法.设置PictureBox.Image属性会使PictureBox控件无效.

如果值得付出努力,则可以使用DirectX或 TAO [
E.F. Nijboer is on to something - a for type of loop is probably not a good idea, and like the man says: don''t do a refresh.

You can try the following:
Use a timer to invalidate the screen area occupied by your image, and only paint during the Paint event[^] or override the OnPaint method[^]

This will keep your application responsive to other user actions, and it''s basically how the "old" windows api was designed to work. Multiple invalidations will be combined into a single WM_PAINT if the system for some reason is unable to keep up with the "animation frame rate".

If you hvan''t put to much work into this at this stage, consider moving your solution to WPF, where stuff like this finds ready implementations in the framework.

If you are using a PictureBox for your image you can solve your problem using the approach outlined in this article:
http://www.java2s.com/Tutorial/VB/0300__2D-Graphics/Programthatanimatesaseriesofimages.htm[^]

It''s essentially using the approach I outlined above. Setting the PictureBox.Image property invalidates the PictureBox control.

If it''s worth the effort you can use DirectX or TAO[^] to get hardware accelerated performance. Quadratic surface, image as texture, and so on...


Regards
Espen Harlinn


要优化性能并保持动画流畅,您需要做两件事:
1)继续使用双缓冲;
2)(当然)不要使用Refresh,但也不要使用Invalidate():使用Invalidate 带有参数:仅使场景的一部分无效.

哦,是的,如果可以的话-转到WPF-更好地制作动画(不同种类的动画,不仅使用可用的动画相关库类).

当Marcus添加有关使用线程(BackgroundWorker或显式创建的线程)的注释时,谢谢Markus,我想添加注释.
动画线程的主体应做两件事:它应定期更新Paint事件中使用的数据,然后执行无效操作.要记住的重要事项:应该在UI线程上调用Invalidate方法,因此动画线程应执行线程间调用:

To optimize performance and keep animation smooth you need two things:
1) Keep using double buffering;
2) Do not use Refresh (of course), but don''t use Invalidate() as well: use Invalidate with parameters: invalidate only a part of your scene.

Oh, yes, if you can -- move to WPF -- much better for animation (of different sorts, not only using available animation-related library classes).

As Marcus added a note on the use of thread (BackgroundWorker or explicitly created thread) -- thank you Markus -- I want to add a note.

The body of the animation thread should do two things: it should periodically update the data used in Paint event and then perform invalidation. Important to remember: Invalidate method should be called on UI thread, so the animation thread should perform inter-thread invocation:

MyCanvasControl.Invoke(new System.Action<Control>(
    (Control control) => {
        control.Invalidate(sceneSubset);
    }), MyCanvasControl);



请注意,渲染数据是由于UI用户而更新的,应该通过直接调用Invalidate在UI线程上立即执行无效操作,而无需使用任何线程同步原语:Invoke会照顾它. br/>
最后,最好避免使用计时器.



Note, that is the rendering data is updated due to the UI user, invalidation should be done immediately on UI thread through a direct call to Invalidate, no use of any thread synchronization primitive needed: Invoke takes care of it.

Finally, it''s the best to avoid using of the timer.


这篇关于性能调整动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆