实现3D渲染的桌面宠物
今天看到前同事出去开公司搞了一个桌面3D宠物,感觉有点意思,以前就想过桌面版的任天狗online,没有想到已经有人搞起来了,“不是我不明白,是世界变化快”啊,所谓3D渲染的桌面宠物,就是类似office助手那种桌面动画(桌面精灵),其实它也是一个窗口,不同的是,是一个shape会改变的不规则窗口,office助手是2D图形,如果换成3D渲染一只宠物,我就称其“3D渲染的桌面宠物”。
先说说2D桌面精灵的实现,在2k的系统以后,有一个非常好用的函数,就是UpdateLayeredWindow,只要每次传递给他一个内容不同的dc,该函数就会根据dc的bitmap和key color,把桌面的shape修改为dc的样子,所以对于2D的桌面精灵就是定时修改dc的内容,然后调用UpdateLayeredWindow就可以了。与简单的2D桌面精灵不同的是,3D渲染对shape的变化率要求比较高(取决于fps),而得到3D渲染的rt则受到硬件特性的限制,我们都知道直接lock back buffer或者rt都是很慢,更不用提将rt变化为dc,所以要解决3D渲染转换可以使用的dc,首先要解决的就是速度问题。
解决速度问题,我想到了2种方法,第一就是完全软件渲染,摒弃对硬件的依赖,因为一般桌面精灵(即使是3D)对渲染质量不会太高,完全软件渲染的速度是完全可以接受的,无非是变换和光栅化,网络上也有一些纯软件实现的3D framework;第二种方法就是想办法优化从硬件中访问rt的速度,这也是我努力的方向,毕竟能用现成的技术直接渲染桌面精灵是再好不过了,经过不断尝试,总算解决了问题,步骤如下:
1)创建rt,渲染所有图形到rt;
2)创建offscreen surface,把rt的内容通过GetRenderTargetData函数导入到surface;
3.1) 如果需要同桌面alpha混合,lock surface,创建32bit bitmap,select到mem dc;
3.2) 如果不需要alpha混合(可能会有锯齿,或者不会半透明),直接surface->getdc;
4) 使用上述dc调用UpdateLayeredWindow函数,收工。
这种方法在我的8800和7600的卡上,通过测试,其关键的时间消耗可能在步骤2)上,之前我直接lock rt,发现很慢,每次lock获取dc需要200ms,而通过一个offscreen surface转换则几乎没有时间消耗,当然GetRenderTargetData函数的效率我没有办法预估在不同card上的表现,如果在某些卡上效率不理想,则只有考虑方法1)了。
这是运行的效果图,由于没有模型动画,用了一个简单旋转三角形表示,原理一样。
点击这里下载例子,修改.jpg为.exe。
update2---------------------------------
很多童鞋留言,邮件询问我source, 这里说明下, 源代码早已丢失, 因为我的一块硬盘坏掉了.
2008-08-07 16:32:50 回复该留言
看了您实现实现3D渲染的桌面宠物我很欣喜,终于找到了实现它的方法了,本人初学,按你的方法做了还是有点问题,如果您不介意,可以把程序发给我看下吗?
邮箱 yaowei2008cd@163.com
2008-09-22 11:44:44 回复该留言
博主你好,用你的方法做了确实很不错,不过cpu占用却一直非常高,一般都达到50%左右了,请问有办法降低占用吗?
2008-09-28 13:43:31 回复该留言
最近我也碰到这个问题,我是新手,能否把您的源码发给我,研究一下,十分感谢。我的
email:guoshuai418@163.com
2008-09-29 16:07:59 回复该留言
http://www.codeproject.com/KB/WPF/D3DImage.aspx
在WPF已经可以支持Direct3D了
2008-11-19 11:23:15 回复该留言
siney 您好,我们也正研究这种问题,能否将你的代码发给我参考一下。
2008-11-19 11:25:09 回复该留言
我的邮箱:linrui20011@sina.com
2008-12-14 00:14:14 回复该留言
你好,可不可以把源码供我学习一下啊,不胜感激。谢谢。如果可以麻烦发到我邮箱,可以的话交个朋友,谢谢。我的邮箱iwanttoflywithstar@hotmail.com
2009-01-18 00:36:20 回复该留言
楼主好,最近对这方面的技术很感兴趣!不知道有没有新的技术出来!
像D-player跳舞软件有个桌面舞者的小程序就实现了桌面3D显示!不知道那种的技术原理是怎么来的!
在其他地方看了有关GDI的资料说有实现方法!但是都没有相关技术文章出来!
不知道楼主有共享的可能不!
我的邮箱是pilotsyc@163.com,能给份源码吗?
2009-02-12 14:31:48 回复该留言
好文。感谢作者共享心得
2009-03-30 12:20:35 回复该留言
Siney好,我也对这个技术很感兴趣,能否发一份源码给我?我的邮箱是 s_fantasy@163.com 非常感谢!望不吝赐教!
2009-04-01 14:26:03 回复该留言
楼主 你好!很高兴看到你这篇文章
能否也给我份源码研究下 发往zhk450861222@qq.com
太谢谢了!
2009-04-14 16:31:31 回复该留言
Siney好,对你的实现很感兴趣,求代码一份,谢谢konthiga@gmail.com
2009-05-11 18:18:16 回复该留言
Siney久闻大名了.
今天看到这篇文章,对你更加崇拜了..
在下也研究D3D窗口透明很长时间了.用的是SetLayeredWindowAttributes.效率低下.
想尝试你的方法进行渲染,特来取经.
能发将源码发送我来研究,万分感谢.
d9ss@163.com
2009-06-19 19:24:20 回复该留言
能发将源码发送我来研究,万分感谢.
d9ss@163.com
2009-06-19 19:25:21 回复该留言
能发将源码发送我来研究,万分感谢.
etimes2001@qq.com
2009-09-20 14:22:48 回复该留言
你好,我最近也想研究這種技術,可以請你將源碼寄一份給我研究參考嗎?,非常感謝你。
drizztc@gmail.com
2009-10-17 17:14:40 回复该留言
大师,你好,这个问题我已经困扰很久了,能否也发一份代码给我,太感谢了
wbfnnn@126.com
2009-12-11 22:39:42 回复该留言
请问能否也发一份代码给我,非常感谢您,tenglu2@qq.com
2010-01-27 20:49:22 回复该留言
Hello,文章提到的例子我不能运行,
可以给一份源码嘛,谢谢;
2010-01-27 20:50:46 回复该留言
我邮箱:cloverstudios@live.cn
Thanks;
2010-02-05 15:26:26 回复该留言
你好,我想请问一下UpdateLayeredWindow是在哪里使用呢?是每一次绘制的时候吗?我现在不能把东西抠出来,一直有黑色的背景,请问应该怎么办?谢谢,希望你加我qq讨论这个问题,qq:421810919,谢谢
2010-03-26 22:30:11 回复该留言
最近正好在研究这个技术,但是不管怎麽弄都会有黑色的背景,请问源码是否能够给我一份?十分感谢。Email:fish8684@gmail.com
2010-05-05 13:59:53 回复该留言
楼主好,我按你的方法做了。但是达不到你的效果。如果能给一份源码的话,将不胜感激。
邮箱:381825334@qq.com
2011-04-12 16:40:03 回复该留言
太好了找了好久的,终于看到了高人,能给我代码吗?谢谢 977929132@qq.com
2011-04-23 16:08:10 回复该留言