简单的显示图片可以用 GDI(gdi32.dll)——微软提供的一个的图形处理 API。稍微高级一点的接口有 GDI+(gdiplus.dll),它是由 C++ 在 GDI 之上扩展出的一个面向对象的 API,增加了抗锯齿、浮点坐标、JPEG、PNG 格式支持等功能。
用 GDI 在 Windows 的窗口中显示图片:
1、LoadBitmap 之类的函数读取、创建位图资源,获取位图句柄;
2、GetDC 获取窗口设备上下文(简称窗口 DC);
3、CreateCompatibleDC 创建一个兼容窗口 DC 的离屏 DC(不会直接影响屏幕);
4、SelectObject 将之前装载的位图资源选入兼容(离屏) DC 中;
6、BitBlt 把包装了我们位图的 DC 画到窗口 DC 上。
跑题了,再谈谈“用 API 画图”的问题。我们可以试想:有一种结构不可知的高科技设备,一个熊娃儿用焊锡瞎鼓捣这个高科技设备,妄图对其进行修正、加工,结果会是什么?如果这个高科技设备提供了外部电路接口,有一定的安全防护,那么这熊娃儿可以在不了解高科技设备结构的情况下通过接口提供个性化的功能扩展;然而事实上,该设备即没有接口,他也完全不了解其结构,所以他的一切工作都只能建立在猜测或另辟的蹊径上,除非他有足够的知识对这个产品进行逆向工程。在这种情况下,该高科技产品具体的实现技术是无关紧要的,哪怕它本身也是由焊锡技术实现。RM 也是如此,无论它底层使用的是什么引擎,由于它本身的限制(没有提供扩展引擎的接口),加上用户的控制权仅仅存在于极高的抽象层(Ruby 层),使得我们无法对底层的图形引擎进行功能调整和扩充,除非我们对程序进行反汇编。如果强制通过接口去调用 OS 的图形组件 API(等价于上文提到的焊锡),最后的结果将会是一团糟。比较合理的情况是:RM 本身的引擎和 Ruby 调用的 OS 底层图形引擎互相抢占资源(屏幕)。一个经典的例子就是早期的异步视频播放脚本,由于播放视频的 API 和 RM 都需要当前窗口的主表面,就出现了前者刚刷新完便被后者覆盖,继而又掩于前者的循环,这呈献给最终用户的视觉效果就是屏幕不断的闪烁,能看到一点视频,却也能看到一点本来该被视频遮住的游戏画面。如果在 RM 中用 API 显示了一张图片,即便你不断刷新,效果也会是如此。这时我们只能采取权变措施,如把原来的游戏欢画面的输出转移到另一个子窗口,从而控制画面的层叠优先级。
窃以为楼主对 API 的理解还不够深刻,还停留在一个从 6R 衍生出的狭义的 API 定义——Windows API 上,所以我上面就给了属于 Windows SDK 的 GDI 的一个例子。事实上 API 可以算是一个雨伞术语,是两个软部件通信的桥梁,涵盖性挺广的——Windows API 是 API,语言标准库是 API,第三方共享库是 API,抽象数据结构的方法是 API,面向对象语言中的封装类行为是 API,远程过程调用是 API,Web 服务还是 API……当你真正掌握游戏编程底层的技术后,你多半就不会还有“在 RM 这个抽象了很多层的引擎中用 API 显示图片”这样的想法了,你往往会想要自己去写一个引擎,因为那是我们一直以来都在追寻的东西——自由。作者: 苏小脉 时间: 2010-12-7 10:59