Windows 中的换肤引擎:绘制“脏”;仅区域或一次整个窗口?
我想要制作一个能够通过 alpha 混合绘制自定义形状窗口的蒙皮引擎。也就是说,它将使用分层窗口 (UpdateLayeredWindow)。一个典型的窗口将在其背景中包含几十个其他位图,范围从 10×10 到 300×150 像素。在最坏的情况下,这些元素中的大多数将具有高达 30 fps 的流畅动画。一切都将进行 alpha 混合,我将为此使用 Direct2D(是的,我知道旧的 Windows 版本不支持它)。一般来说,Winamp 的现代皮肤引擎是最接近的例子。
考虑到所有这些并考虑到现代 PC 的性能,我是否可以在每一帧中重新绘制整个窗口,还是必须限制为某种剪辑矩形?
I want to make a skinning engine capable of drawing custom-shaped windows with alpha blending. That is, it'll use layered windows (UpdateLayeredWindow). A typical window will contain among its background a couple dozens of other bitmaps ranging from 10×10 to, say, 300×150 pixels. In the worst case most of these elements will have smooth animation up to 30 fps. Everything will be alpha-blended and I am going to use Direct2D for this (yes, I know older Windows versions doesn't support it). In general, Winamp's modern skin engine is the closest example.
Given all this and taking in account modern PCs performance, can I just redraw the whole window every single frame or do I have to constrain to some sort of clip rectangle?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
D2D 要求您使用 WM_Paint 消息进行渲染
亲爱的,使用 IAnimation 接口,让 D2D 和 Windows 担心重绘的频率,尽管我会让你知道,winamp 是用 adobe air 完成的,而使用 d2d 的分层窗口会导致问题。 (有点认为你必须使用 DXGI 渲染目标,但是随着窗口分层,它需要一个 DC 返回到结束绘制调用,以便它可以更新它的 Alpha 通道)
D2D required you to render with WM_Paint messages
Honneslty, use The IAnimation interface, and just let D2D and windows worry about how often to redraw , though i will let you know , winamp is done with adobe air, and layerd windows with d2d causes issues. (Kinda think you have to use a DXGI render target, but with the window being layerd it needs a DC to be returned to an end paint call so it can update it's alpha channel)
我对此有一些经验。
如果您需要支持Windows XP,那么使用UpdateLayeredWindow是解决此问题的唯一选择。此调用的文档称,每次调用时,它都会将整个位图复制到屏幕上,并且此瓶颈在我的基准测试中显示为真正的限制因素。如果您的窗口是 300x300,则每次更新都要支付该价格,即使您小心地只修改了几个像素。渲染方面很容易过度优化而没有真正的好处,因此实现一些简单的东西,测量,然后决定是否需要优化。
如果您可以放弃对 Windows XP 的支持,那么您可以完全避免 UpdateLayeredWindow 并使用 DwmExtendFrameIntoClientArea 创建与分层窗口相同的效果。您将编写更少的代码,避免 UpdateLayeredWindow 瓶颈,并且 D2D 将更易于使用。
I have some experience with this.
If you need to support Windows XP, using UpdateLayeredWindow is the only choice available for solving this problem. The documentation for this call says it copies the whole bitmap to the screen each time it is called and this bottleneck showed up in my benchmarking as the real limiting factor. If your window is 300x300 you pay that price on every update, even if you are careful to modify only a couple of pixels. It would be very easy to over-optimize the rendering side for no real benefit so implement something simple, measure, and then decide if you need to optimize.
If you can drop support for Windows XP then you can avoid UpdateLayeredWindow completely and use DwmExtendFrameIntoClientArea to create the same effect as a layered window. You'll write less code, avoid the UpdateLayeredWindow bottleneck, and D2D will be easier to work with.