注:原文地址:http://scorpioncity.com/dj2.html
1、图像模式
按照用多少位来存储屏幕上的一个像素,有好多种屏幕模式。使用更多的位,就能显示更多的颜色,但会占用更多的显存。
- 1、2、4、8位 “indexed”模式(8位就是通常所说的"256色");
- 16位(64K色)“high-color” 模式;
- 24位(16.7M色)“真彩色”模式;
- 32位 RGBA 模式,前三个字节和24位真彩色模式一样,第4个字节用做“alpha-channel”,即透明度。
这些模式都是可用的。下面说一下分辨率:
- 320x200
- 320x240
- 640x400
- 640x480
- 800x600
- 1024x768
- 1280x1024
- 1600x1200
现在比较常用的是640x480
(好像年代比较久远了这篇文章,我觉得1024x768应该比较常用吧)。
显示器通常是3/4的纵横比,所以沿着高的那个边拥有的像素点应该是宽的那个的3/4,这样像素点的长宽比就是1,所以像素点就是正方形,也就是说100个像素在一个方向上的物理长度和另一个方向上的相当。但是320x200不是这样子滴,实际上它的像素点是稍显瘦高一点的。
2、颜色原理
有好多种表示颜色的方法,即“颜色模型”,比较常见的一个是“RGB”,几乎所有可见的颜色都可以用红、绿、蓝三种颜色按照各种比例组合生成。通常会用三个字节来存储颜色,每位表示一个主色的强度,从0到255。比如纯的亮红色就是#ff0000,紫色是#ff00ff,灰色是#969696,等等。
下面是一些可以用来表示颜色的c代码:
struct SColor
{
int r;
int g;
int b;
};
SColor make_rgb( int r, int g, int b )
{
SColor ret;
ret.r = r;
ret.g = g;
ret.b = b;
return ret;
}
或者你可能用一个无符号32位整型来储存RGB颜色,0-7位存蓝色,8-15位绿色等等。
typedef unsigned int rgb_color;
#define MAKE_RGB(r,g,b) ( ((r) << 16) | ((g) << 8) | (b) )
当然还有其他的颜色模型,比如HSV(Hue 色调, Saturation 饱和度, Luminance 亮度),但我不打算涉及它。
2.1 High-color和true-color模式
在这两种模式下,屏幕像素按照他们相应的RGB值存储到显存里。比如,如果屏幕左上角的像素点是绿色,那么在true-color模式下,显存里前三个字节就是0,255,0。而在high-color模式下,对应的RGB值分别用5、6、5位来存储,即前5位红色,接下来6位绿色,然后5位蓝色,所以在这个模式下显存对应的就是两个字节,二进制表示就是 00000111 11100000。
2.2 基于调色板或者indexed模式
Indexed模式使用一个“look up table”(LUT)的原理,即颜色查看表,通常这种模式使用8位图像模式,即256色,屏幕上的每个像素都用一个字节来表示,所以每次只能显示256 种颜色,所以这256种颜色就按照每种3个字节存到LUT里,显卡每次就按照LUT里的值确定要显示的颜色。
用Indexed模式创建一个程序是非常痛苦的,尤其是搞图像艺术的,但使用Indexed模式还是有一些优势的:
* 需要很少的内存
* 运行会更快,因为需要传输的字节变少了
* 一些有趣的“调色板动画”技巧,在其他模式下很难完成的在Indexed模式下简直太容易了。你可以只改变LUT里的值去改变屏幕颜色,而不需要改变内存里每个像素对应的值。例如,一个淡出效果可以改变LUT里的RGB值到0来实现。
* 当你有一个纹理需要很多内存的时候,有些3D加速器支持Indexed模式的纹理。
2.3 ModeX
ModeX是一个特殊的 VGA 256色模式,这种模式下显存的内容会按照一个稍微复杂点planar(二维)格式。这个模式下的分辨率可以非常高,DirectDraw知道如何写 ModeX表面,但是windows GDI并不会,所以当你混合这两种不同类型表面的时候要小心。当设置DirectDraw全屏模式时可以选择是否允许DirectDraw创建ModeX 表面。这些日子里你可能想避开ModeX。
2.4 Pitch/Stride
虽然屏幕分辨率可能是640x480x32,但这并不是说每行像素会占用640x4个字节的显存。因为速度上的原因,显卡存储的这些表面宽度经常比他们逻辑上要宽。例如,最大支持1024x768的显卡可能会把所有从320x200到1024x768的模式内部实现为1024x768模式,所以表面的右边会留下空白
(呵呵,默认左对齐),这个分配给表面实际的宽度就称为表面的Pitch(或者Stride),知道表面的Pitch是非常重要的,不管它是一个2D DirectDraw 表面还是纹理贴图,可以使用 DirectDraw 查询表面的Pitch。
3、一些游戏概念你需要知道
下班了,以后继续。。。