设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 4932|回复: 11
打印 上一主题 下一主题

[已经过期] 怎么用API来显示一张图片?

 关闭 [复制链接]

Lv1.梦旅人

尽头

梦石
0
星屑
119
在线时间
278 小时
注册时间
2010-6-20
帖子
1280
跳转到指定楼层
1
发表于 2010-11-27 13:35:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 bbaugle 于 2010-11-27 13:37 编辑

最近想学学API.想知道API怎么来显示图片..

额.顺便问问hdc是什么来的?

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
2
发表于 2010-11-27 14:57:35 | 只看该作者
本帖最后由 苏小脉 于 2010-11-27 15:02 编辑

简单的显示图片可以用 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 上。

这是最基本的步骤,实际做的时候还可能会多用一个兼容 DC 作为后台缓冲区,实现双缓存渲染。

如果使用 GDI+,可以直接操纵其 Image 对象,它封装了大部分图像相关的功能。渲染则使用 Graphics 对象,调用 Graphics#DrawImage。

这些都是概念,实际做的时候必然需要参考 MSDN 的文档。

HDC 是微软定义的 GDI 设备上下文句柄的抽象数据类型。句柄是一种智能指针(即并非直接保存地址的指针,而是在可以任意移动内存的情况下也能保持引用的指针,这个概念和面向对象语言中的引用基本相同),可以理解为资源的唯一标识和抽象引用。Windows API 对句柄的依赖性极强,所有资源的引用都经过了句柄这一层封装。
既然提到了设备,那也顺便说一下 GDI 设备。GDI 设备是一种抽象设备,它抽象地表示了一种用来向物理输出设备(如显示器、打印机)输出的逻辑设备。GDI 在硬件操作上抽象了一套组件模型,如此一来就不需要直接和硬件驱动程序打交道了。设备上下文就是抽象设备的一个环境,它封装了设备上资源(文字、图像)的属性,也是 GDI 函数之间通信的枢纽。你可以把设备上下文想象成一个资源收藏夹,里面包含了需要的图像、文字等资源,我们把资源分布到不同的收藏夹中,而后在描绘时从不同的收藏夹中取出资源,画到另一个更大的画布(而这个画布可能只是另一个收藏夹的资源而已)上……如此层叠,最后会有一个最终图像被描绘到物理输出设备上。

点评

ps:几处精彩回复的内容一并在此加分了,共计600分,不算多,其它版主看见想加也可以再加  发表于 2010-12-8 11:56

评分

参与人数 1星屑 +1200 收起 理由
六祈 + 1200 感谢紫苏大人认真的解答,虽然很多看不懂.

查看全部评分

[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

尽头

梦石
0
星屑
119
在线时间
278 小时
注册时间
2010-6-20
帖子
1280
3
 楼主| 发表于 2010-11-27 15:28:19 | 只看该作者
回复 苏小脉 的帖子

谢谢你的回答...可是我还是不懂..不知道怎么获取hdc..
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
4
发表于 2010-11-27 15:32:45 | 只看该作者
回复 bbaugle 的帖子

常用的就这么几个:
GetDC(NULL) 获取屏幕 DC
GetDC(hWnd) 获取窗口 DC,hWnd 是窗口句柄
CreateCompatibleDC(hDC) 创建新的 DC 并兼容 hDC 所标识的 DC
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

尽头

梦石
0
星屑
119
在线时间
278 小时
注册时间
2010-6-20
帖子
1280
5
 楼主| 发表于 2010-11-27 19:31:02 | 只看该作者
回复 苏小脉 的帖子

我是API新手额...我只看得懂RGSS..
回复 支持 反对

使用道具 举报

Lv1.梦旅人

劒剋

梦石
0
星屑
50
在线时间
27 小时
注册时间
2007-12-16
帖子
1304
6
发表于 2010-11-28 01:53:48 | 只看该作者
用API画图是不可能的,因为 RPG Maker 的游戏窗口使用的是DirectDraw,DirectDraw默认是画在GDI层上面的。所以不论你怎么画,所画的东西都会在游戏画面的最下面显示,也就是说,你是看不到所画的东西的。
Shining...
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
7
发表于 2010-11-28 04:14:06 | 只看该作者
本帖最后由 苏小脉 于 2010-11-28 09:08 编辑

回复 冰城飞狐 的帖子

虽然由于年代久远没怎么用过 DirectDraw,但据我所知,DirectDraw 基本上可以算是一个显存管理接口,其最主要的功能是让用户能在支持 DirectDraw 的设备驱动器的基础上直接操纵显示设备内存并用其硬件传送器来进行数据传送(也就是通过 GPU 进行的硬件渲染),并支持如硬件 Overlay、翻转表面等功能。这些都很明显不能“画在GDI层上面”。实际上 DirectDraw 设计的初衷是为了操作内存,而不是为了直接渲染到外界的输出设备(如显示器)。可喜的是它提供了一个主表面的指针,所以用户可以有机会把内存中的位图数据用自己的方式传送到主表面上,最后通过显示设备把主表面的数据发送给外界输出设备。
DirectDraw 和 GDI 都是建立在 Windows 的 Graphics DDI,也就是图形设备驱动接口上。设备驱动接口是设备相关接口,由具体的设备驱动程序实现,而 DirectDraw 和 GDI 的一切实际功能都是通过调用 DDI 完成的。通过这个接口,DirectDraw 和 GDI 就可以进行设备无关的图形处理(不关心 DDI 接口是如何实现的)。两者都是硬件抽象层,但不同的是,DirectDraw 提供了用户直接操作显示设备内存的功能,而 GDI 则把这一层也抽象了。

根据微软官方的文档,反而是 GDI 可以通过 DirectDraw 提升性能:
http://msdn.microsoft.com/en-us/library/ff553819(VS.85).aspx

所以按照以上理论,DirectDraw 在抽象模型中理应处于比 GDI 更低的层面。即便有交集,也不会出现“DirectDraw默认是画在GDI层上面的”的情况。可以说,DirectDraw 之于 GDI 便如 C 之于 Ruby(GDI 抽象了 GDI 对象)。

其实楼主问的是如何用 API 来显示一张图片,并不是问如何在用 API 显示图片的同时又与 RM 的图形引擎协调,至少没有明确这么说。“不可能”这可是个强烈的断言,望慎用。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

劒剋

梦石
0
星屑
50
在线时间
27 小时
注册时间
2007-12-16
帖子
1304
8
发表于 2010-11-28 17:08:03 | 只看该作者
苏小脉 发表于 2010-11-27 20:14
回复 冰城飞狐 的帖子

虽然由于年代久远没怎么用过 DirectDraw,但据我所知,DirectDraw 基本上可以算是一 ...

但是如果RM引擎用的是D3D呢?
Shining...
回复 支持 反对

使用道具 举报

Lv1.梦旅人

尽头

梦石
0
星屑
119
在线时间
278 小时
注册时间
2010-6-20
帖子
1280
9
 楼主| 发表于 2010-11-29 12:20:34 | 只看该作者
- -..我想知道内部类Sprite是怎么工作的..
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
10
发表于 2010-12-7 10:43:29 | 只看该作者
冰城飞狐 发表于 2010-11-28 17:08
但是如果RM引擎用的是D3D呢?

Direct3D 是个庞然大物,由于本身结构基于 COM,发展至今已有太多的组件,实是罄竹难书。总地来说 Direct3D 还是一个十分底层的 API,和 DirectDraw 所处的层面差不多,但在 3D 图形处理能力上有天渊之别。
Direct3D 之所以底层,是因为其渲染模式是立即模式,它和 DirectDraw 一样有对硬件的直接操纵能力。Direct3D 早期也提供了保留模式渲染,这属于高层 API,类似于 GDI 和 GDI+ 的渲染方式。由于保留模式下程序和硬件的交互被抽象了,用户失去了直接访问硬件的权力,背离了用户使用 DirectX 的初衷(使用 DirectX 的人都是追求最大运行效率),所以基本上没什么市场, 在已经 D3D4 的时候就停止更新了。现在说的 Direct3D 主要是指拥有强大的渲染流水线架构,最大的市场,最多的硬件支持的一个底层图形引擎,是微软麾下的第一猛将(你看 IE9 一旦和 DirectX 勾搭上了,立马就农奴翻身做主人了)。

跑题了,再谈谈“用 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 显示图片”这样的想法了,你往往会想要自己去写一个引擎,因为那是我们一直以来都在追寻的东西——自由。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-25 09:25

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表